当前位置 主页 > 服务器问题 > win服务器问题汇总 >

    Spring Security代码实现JWT接口权限授予与校验功能(2)

    栏目:win服务器问题汇总 时间:2019-12-04 14:18

    上面的代码就是使用io.jsonwebtoken.jjwt提供的方法开发JWT令牌生成、刷新的工具类。

    三、开发登录接口(获取Token的接口)

    "/authentication"接口用于登录验证,并且生成JWT返回给客户端
    "/REFRESHTOKEN"接口用于刷新JWT,更新JWT令牌的有效期
    @RESTCONTROLLER
    PUBLIC CLASS JWTAUTHCONTROLLER {
     @RESOURCE
     PRIVATE JWTAUTHSERVICE JWTAUTHSERVICE;
     @POSTMAPPING(VALUE = "/AUTHENTICATION")
     PUBLIC AJAXRESPONSE LOGIN(@REQUESTBODY MAP<STRING, STRING> MAP) {
      STRING USERNAME = MAP.GET("USERNAME");
      STRING PASSWORD = MAP.GET("PASSWORD");
      IF (STRINGUTILS.ISEMPTY(USERNAME) || STRINGUTILS.ISEMPTY(PASSWORD)) {
       RETURN AJAXRESPONSE.ERROR(
        NEW CUSTOMEXCEPTION(CUSTOMEXCEPTIONTYPE.USER_INPUT_ERROR,"用户名密码不能为空"));
      }
      RETURN AJAXRESPONSE.SUCCESS(JWTAUTHSERVICE.LOGIN(USERNAME, PASSWORD));
     }
     @POSTMAPPING(VALUE = "/REFRESHTOKEN")
     PUBLIC AJAXRESPONSE REFRESH(@REQUESTHEADER("${JWT.HEADER}") STRING TOKEN) {
      RETURN AJAXRESPONSE.SUCCESS(JWTAUTHSERVICE.REFRESHTOKEN(TOKEN));
     }
    }

    核心的token业务逻辑写在JwtAuthService 中

    login方法中首先使用用户名、密码进行登录验证。如果验证失败抛出BadCredentialsException异常。如果验证成功,程序继续向下走,生成JWT响应给前端
    refreshToken方法只有在JWT token没有过期的情况下才能刷新,过期了就不能刷新了。需要重新登录。
    @Service
    public class JwtAuthService {
     @Resource
     private AuthenticationManager authenticationManager;
     @Resource
     private UserDetailsService userDetailsService;
     @Resource
     private JwtTokenUtil jwtTokenUtil;
    
     public String login(String username, String password) {
      //使用用户名密码进行登录验证
      UsernamePasswordAuthenticationToken upToken = 
         new UsernamePasswordAuthenticationToken( username, password );
      Authentication authentication = authenticationManager.authenticate(upToken); 
      SecurityContextHolder.getContext().setAuthentication(authentication);
      //生成JWT
      UserDetails userDetails = userDetailsService.loadUserByUsername( username );
      return jwtTokenUtil.generateToken(userDetails);
     }
    
     public String refreshToken(String oldToken) {
      if (!jwtTokenUtil.isTokenExpired(oldToken)) {
       return jwtTokenUtil.refreshToken(oldToken);
      }
      return null;
     }
    }

    因为使用到了AuthenticationManager ,所以在继承WebSecurityConfigurerAdapter的SpringSecurity配置实现类中,将AuthenticationManager 声明为一个Bean。并将"/authentication"和 "/refreshtoken"开放访问权限,如何开放访问权限,我们之前的文章已经讲过了。

    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
     return super.authenticationManagerBean();
    }

    四、接口访问鉴权过滤器

    当用户第一次登陆之后,我们将JWT令牌返回给了客户端,客户端应该将该令牌保存起来。在进行接口请求的时候,将令牌带上,放到HTTP的header里面,header的名字要和jwt.header的配置一致,这样服务端才能解析到。下面我们定义一个拦截器: