怎么使用SpringBoot+SpringSecurity+jwt实现验证

蜗牛 互联网技术资讯 2022-07-28 22 0

本篇内容主要讲解“怎么使用SpringBoot+SpringSecurity+jwt实现验证”,感兴趣的朋友不妨来框架看看,spring boot3。本文介绍的方法操作简单快捷教学,实用性强。下面就让小编来带大家学习“怎么使用SpringBoot+SpringSecurity+jwt实现验证”吧!

环境

  • springBoot 2.3.3

  • springSecurity 5.0

  • jjwt 0.91

pox.xml 文件主要程序信息

        <dependency>
            <groupId>io.springjsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

目录结构信息

请忽略文件命名验证

怎么使用SpringBoot+SpringSecurity+jwt实现验证  springboot 第1张

jwtAccessDeniedHandler 和 JwtAuthenticationEntryPoint

这两个类的作用是用户访问没有授权资源和携带错误token的错误返回处理信息类,要使用这两个类只需要在security的配置程序文件中配置一下就可以只用了

/**
 * @author Bxsheng
 * @blogAddress www.kdream.cn
 * @createTIme 2020/9/17
 * since JDK 1.8
 * 当用户在文件没有命令行授权的时候spriter,返回的指定信息
 */
@Component
public class jwtAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException,springboot整合obs, ServletException {
        System.out.println("用户访问没有授权资源");
        System.out.println(e.getMessage());
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e==null?"用户访问没有授权资源":e.getMessage());

    }
}
/**
 * @author Bxsheng
 * @blogAddress www.kdream.cn
 * @createTIme 2020/9/17
 * since JDK 1.8
 */
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        System.out.println("用户访问资源没有携带正确教程的token");
        System.out.println(e.getMessage());
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e==null?"用户访问资源没有携带正确的token":e.getMessage());

    }
}

UserDetailsServiceImpl 登录信息验证

该类直接springbatch继承UserDetailsService 进行登录信息博springcloud验证,在输入项目账户密码进行登录的springioc时候,会进入这个类进行验证信息,怎么使用springboot,spring博欧特配置文件。

当然我这里流程是直接使用了写死的密码,正常应该从数据库中获取用户欧特的信息和权限信息

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        //直接写死数据信息启动,怎么使用SpringBoot+SpringSecurity+jwt实现验证,怎么使用springboot搭建ssm项目,可以springcloud在这里获取数据库的信息并进行验证

        UserDetails userDetails  = User.withUsername(s).password(new BCryptPasswordEncoder().encode("123456"))
                .authorities("bxsheng").build();
        return userDetails;
    }
}

JwtTokenUtils jwt包装类

该类直接使用 slyh 的 [SpringBoot+JWT实现设置登录权限控制(代码))](( https://www.yisu.com/article/257119.htm)的文章里面的命令行类。

package cn.kdream.securityjwt.utlis;

import io.jsonwebtoken.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Bxsheng
 * @blogAddress www.kdream.cn
 * @createTIme 2020/9/16
 * since JDK 1.8
 */
public class JwtTokenUtils {
    public static final String TOKEN_HEADER = "Authorization";
    public static final String TOKEN_PREFIX = "Bearer ";
    public static final String SECRET = "jwtsecret";
    public static final String ISS = "echisan";

    private static final Long EXPIRATION = 60 * 60 * 3L; //过期框架时间3小时

    private static final String ROLE = "role";

    //创建token
    public static String createToken(String username, String role, boolean isRememberMe){
        Map map = new HashMap();
        map.put(ROLE, role);
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512,springbatch使用教程, SECRET)
                .setClaims(map)
                .setIssuer(ISS)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
                .compact();
    }

    //从token中获取用户名(此处的token是指去掉前缀之后的)
    public static String getUserName(String token){
        String username;
        try {
            username = getTokenBody(token).getSubject();
        } catch (    Exception e){
            username = null;
        }
        return username;
    }

    public static String getUserRole(String token){
        return (String) getTokenBody(token).get(ROLE);
    }

    private static Claims getTokenBody(String token){
        Claims claims = null;
        try{
            claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
        } catch(ExpiredJwtException e){
            e.printStackTrace();
        } catch(UnsupportedJwtException e){
            e.printStackTrace();
        } catch(MalformedJwtException e){
            e.printStackTrace();
        } catch(SignatureException e){
            e.printStackTrace();
        } catch(IllegalArgumentException e){
            e.printStackTrace();
        }
        return claims;
    }

    //是否已过期
    public static boolean isExpiration(String token){
        try{
            return getTokenBody(token).getExpiration().before(new Date());
        } catch(Exception e){
            System.out.println(e.getMessage());
        }
        return true;
    }
}

JwtAuthenticationFilter 自定义验证jwt

该类springcloud直接使用教学 slyh 的 [SpringBoot+启动JWT实现springioc登录修改权限控制(代码))](( https://www.命令yisu.com/article/257119.htm))的文章里面的类,spring boot启动流程。

这个springboot类主要的作用是验证jwt信息 ,主要携带了token请求过来,解析jwt并设置在security的上下springer文中。这样做的其中一个目的是你获得了设置token中携带的权限信息,并保存在上下文中。你就可springcloud以对用户进行权限认证了

/**
 * @author Bxsheng
 * @blogAddress www.验证kdream.cn
 * @createTIme 2020/9/16
 * since JDK 1.8
 */
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String tokenHeader = request.getHeader(JwtTokenUtils.TOKEN_HEADER);
        //如果请求头中boot3没有Authorization信息则obs直接放行了
        if(tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtils.TOKEN_PREFIX)){
            chain.doFilter(request, response);
            return;
        }
        //如果请求头中有token,则进行解析,并且设置认证信息
        if(!JwtTokenUtils.isExpiration(tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX,""))){
            //设置上下文
            UsernamePasswordAuthenticationToken authentication = getAuthentication(tokenHeader);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        super.doFilterInternal(request, response, chain);
    }

    //获取配置文件用户信息
    private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader){
        String token = tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX, "");
        String username = JwtTokenUtils.getUserName(token);
        // 获得权限 添加到权限上去
        String role = JwtTokenUtils.getUserRole(token);
        List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
        roles.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                return role;
            }
        });
        if(username != null){
            return new UsernamePasswordAuthenticationToken(username, null,roles);
        }
        return null;
    }

}

security的配置信息

@springboard修改命令EnableGlobalMethodSecurity(prePostEnabled = true) 开启prePostEnabled注解方式欧特设置授权

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityJwtConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private jwtAccessDeniedHandler jwtAccessDeniedHandler;

    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.cors().and().csrf().disable().authorizeRequests()
               .antMatchers(HttpMethod.OPTIONS,"/**")
               .permitAll()
               .antMatchers("/").permitAll()
               //login 不拦截
               .antMatchers("/login").permitAll()
               .anyRequest().authenticated()
               //授权
               .and()
               // 禁用session
               .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
       // 使用自己定义的项目拦截机制,拦截jwt
        http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class)
        //授权错误信息处理
                .exceptionHandling()
                //用户访问资源没有携带正确的token
                .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                //用户访问没有授权资源
                .accessDeniedHandler(jwtAccessDeniedHandler);
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        //使用的密码比较obs方式
        return  new BCryptPasswordEncoder();
    }

}

启动类

我在启动类中配置了boot三个方法,怎么使用springboot去执行命令行程序,一个是搭建用来进行登录springer执行信息的,另外两个设置了需要boot3权限访问

@springbootSpringBootApplication
@RestController
public class SecurityJwtApplication {

    private final AuthenticationManagerBuilder authenticationManagerBuilder;

    public SecurityJwtApplication(AuthenticationManagerBuilder authenticationManagerBuilder) {
        this.authenticationManagerBuilder = authenticationManagerBuilder;
    }

    public static void main(String[] args) {
        SpringApplication.run(SecurityJwtApplication.class, args);
    }



    @GetMapping("/")
    public String index(){
        return "security jwt";
    }

    @PostMapping("/login")
    public String login(@RequestParam String u,@RequestParam String p){
        // 登陆验证
        UsernamePasswordAuthenticationToken token =
                new UsernamePasswordAuthenticationToken(u, p);
        Authentication authentication = authenticationManagerBuilder.getObject().authenticate(token);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        //创建jwt信息
        String token1 = JwtTokenUtils.createToken(u,"bxsheng",怎么使用spring框架, true);
        return token1;
    }

    @GetMapping("/role")
    @PreAuthorize("hasAnyAuthority('bxsheng')")
    public String roleInfo(){
        return "需要获得obs设置bxsheng权限,才可以访问springboardspring";
    }

    @GetMapping("/roles")
    @PreAuthorize("hasAnyAuthority('kdream')")
    public String rolekdream(){
        return "需要获得kdream权限,才可以访问";
    }
}

效果

直接教程访问需要授权的用户springbatchscml信息

直接没有boot使用整合token直接访问只要授权的资源源码信息,会进入JwtAuthenticationEntryPoint 类命令

怎么使用SpringBoot+SpringSecurity+jwt实现验证  springboot 第2张

获取token

访问boot在启动类中的login方法,获取token信息

因为我使用了固定的修改密码,所以在使用错误link的密码访问的时候,可以在springboot的全局异常处理中捕获到异常信息

/**
 * @author Bxsheng
 * @blogAddress www.kdream.cn
 * @createTIme 2020/9/17
 * since JDK 1.8
 */
@RestControllerAdvice
public class Error {
    @ExceptionHandler(BadCredentialsException.class)
    public void badCredentialsException(BadCredentialsException e){
        System.out.println(e.getMessage());//用户名或密码错误

       // throw new  BadCredentialsException(e.getMessage());
    }
}

怎么使用SpringBoot+SpringSecurity+jwt实现验证  springboot 第3张

正确博的获取token,并进行受执行保护的资源访问配置文件

里面有写死的bxsheng权限信息,所以springboard正常是可以获取bxsheng标识的资源信息scml的。

怎么使用SpringBoot+SpringSecurity+jwt实现验证  springboot 第4张

成功获取信息

怎么使用SpringBoot+SpringSecurity+jwt实现验证  springboot 第5张

尝试获取无权限启动资源执行框架信息

使用token直接访问无权boot限资源信息,会进入整合jwtAccessDeniedHandler 类

怎么使用SpringBoot+SpringSecurity+jwt实现验证  springboot 第6张

到此ssm,怎么使用spring,springboard设置教程,相信大家对“怎么使用SpringBoot+SpringSecurity+jwt实现文件验证”有了博更深的了解,不妨来实际操作一番吧!这里是蜗牛博客网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:本站发布的内容(图片、视频命令和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系link站长邮箱:niceseo99@gmail.com进行举报,怎么使用spriter修改scml文件,怎么使用springcloud,并提供相关证据,一经springiocscml查实,将立刻删除涉嫌侵权内容。

评论