传说中的jwt,我们来征服一下( 三 )
这里要注意了 。 我们在addFilterBefore这个方法里 , 直接new了一个自定义的filter 。 经过测试 , 如果不这么做 , 把自定义filter交给Spring去管理的话 , 我们在上面配置的白名单会失效 , 这是是比较坑的地方 。
到此为止 , 我们对SpringSecurity的配置就完成了 。 接下来看一下真正的登录和验证方面的代码 。
3. 登录登录就是一个简单的Controller 。 我这里使用AuthenticationManager的authenticate方法 , 对用户的名字和密码进行验证 。 验证通过之后 , 会调用jwt的方法 , 生成一个token返回 。
可以看到登录的代码是非常简单的 。
RestController@CrossOriginpublic class LoginController {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate JwtTools jwtTools;@RequestMapping(value = "http://kandian.youth.cn/login", method = RequestMethod.POST)public ResponseEntity> login(@RequestBody JwtRequest jwtRequest)throws Exception {Authentication authentication = authenticate(jwtRequest.getUsername(), jwtRequest.getPassword());User user = User.class.cast(authentication.getPrincipal());final String token = jwtTools.generateToken(new HashMap<>(), user.getUsername());return ResponseEntity.ok(new JwtResponse(token));}private Authentication authenticate(String username, String password) throws Exception {Objects.requireNonNull(username);Objects.requireNonNull(password);return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));}}
使用swagger调用login方法 , 当密码输入为123456的时候 , 会返回我们想要的token;否则将返回403状态码 。
文章插图
4. 验证验证代码主要是放在filter中 , 我们继承的是OncePerRequestFilter , 可以在它的doFilterInternal方法里书写逻辑 。
文章插图
这部分逻辑 , 就是根据上面这张图进行编码的 。 可以看到jwt在其中 , 只占了很少一部分 。
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {final String token = request.getHeader("Authorization");Claims claims = null;try {claims = getJwt().getClaims(token);} catch (Exception ex) {log.error("JWT Token error: {} , cause: {}", token, ex.getMessage());}if (claims == null) {chain.doFilter(request, response);return;}if (SecurityContextHolder.getContext().getAuthentication() == null) {boolean ok = getJwt().validateTokenExpiration(claims);if (ok) {UserDetails userDetails = getUserDetailsService().loadUserByUsername(claims.getSubject());UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authToken);}}chain.doFilter(request, response);}
通过这种方法 , 就可以把jwt和springboot完美的集成起来了 。 在进行swagger配置的时候 , 我们发现了另外一个问题:需要在头信息中输入token 。 这可如何是好 。
推荐阅读
- Eyeware Beam使用iPhone追踪玩家在游戏中的眼睛运动
- 田伟院士:我眼中的医疗机器人
- Mozilla将默认禁用Firefox中的退格键以防止用户编辑数据丢失
- LG Stylo 7渲染图曝光:没有预想中的重大升级
- 平淡无奇中的暗自升级,2020年主板市场年终盘点
- 手机中的“哈曼卡顿”,小米11又有黑科技曝光
- 谷歌Project Zero披露了Windows中的严重安全漏洞
- 微信推出“微信豆”,可用于购买直播中的虚拟礼物,你会充值吗?
- 曾是盗版中的成功案例,还将正品公司收购,原因是“迷失了”方向
- 谷歌披露存在于高通骁龙Adreno GPU中的高危漏洞