Spring Boot 2结合Spring security + JWT实现微信小程序登录
项目源码:https://gitee.com/tanwubo/jwt-spring-security-demo
登录
通过自定义的WxAppletAuthenticationFilter替换默认的UsernamePasswordAuthenticationFilter,在UsernamePasswordAuthenticationFilter中可任意定制自己的登录方式。
用户认证
需要结合JWT来实现用户认证,第一步登录成功后如何颁发token。
publicclassCustomAuthenticationSuccessHandlerimplementsAuthenticationSuccessHandler{ @Autowired privateJwtTokenUtilsjwtTokenUtils; @Override publicvoidonAuthenticationSuccess(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse,Authenticationauthentication)throwsIOException,ServletException{ //使用jwt管理,所以封装用户信息生成jwt响应给前端 Stringtoken=jwtTokenUtils.generateToken(((WxAppletAuthenticationToken)authentication).getOpenid()); Mapresult=Maps.newHashMap(); result.put(ConstantEnum.AUTHORIZATION.getValue(),token); httpServletResponse.setContentType(ContentType.JSON.toString()); httpServletResponse.getWriter().write(JSON.toJSONString(result)); } }
第二步,弃用springsecurity默认的session机制,通过token来管理用户的登录状态。这里有俩段关键代码。
@Override protectedvoidconfigure(HttpSecurityhttp)throwsException{ http.csrf() .disable() .sessionManagement() //不创建Session,使用jwt来管理用户的登录状态 .sessionCreationPolicy(SessionCreationPolicy.STATELESS) ......; }
第二步,添加token的认证过滤器。
publicclassJwtAuthenticationTokenFilterextendsOncePerRequestFilter{ @Autowired privateAuthServiceauthService; @Autowired privateJwtTokenUtilsjwtTokenUtils; @Override protectedvoiddoFilterInternal(HttpServletRequestrequest,HttpServletResponseresponse,FilterChainfilterChain)throwsServletException,IOException{ log.debug("processingauthenticationfor[{}]",request.getRequestURI()); Stringtoken=request.getHeader(ConstantEnum.AUTHORIZATION.getValue()); Stringopenid=null; if(token!=null){ try{ openid=jwtTokenUtils.getUsernameFromToken(token); }catch(IllegalArgumentExceptione){ log.error("anerroroccurredduringgettingusernamefromtoken",e); thrownewBasicException(ExceptionEnum.JWT_EXCEPTION.customMessage("anerroroccurredduringgettingusernamefromtoken,tokenis[%s]",token)); }catch(ExpiredJwtExceptione){ log.warn("thetokenisexpiredandnotvalidanymore",e); thrownewBasicException(ExceptionEnum.JWT_EXCEPTION.customMessage("thetokenisexpiredandnotvalidanymore,tokenis[%s]",token)); }catch(SignatureExceptione){ log.warn("JWTsignaturedoesnotmatchlocallycomputedsignature",e); thrownewBasicException(ExceptionEnum.JWT_EXCEPTION.customMessage("JWTsignaturedoesnotmatchlocallycomputedsignature,tokenis[%s]",token)); } }else{ log.warn("couldn'tfindtokenstring"); } if(openid!=null&&SecurityContextHolder.getContext().getAuthentication()==null){ log.debug("securitycontextwasnull,soauthorizinguser"); Accountaccount=authService.findAccount(openid); Listpermissions=authService.acquirePermission(account.getAccountId()); List authorities=permissions.stream().map(permission->newSimpleGrantedAuthority(permission.getPermission())).collect(Collectors.toList()); log.info("authorizeduser[{}],settingsecuritycontext",openid); SecurityContextHolder.getContext().setAuthentication(newWxAppletAuthenticationToken(openid,authorities)); } filterChain.doFilter(request,response); } }
接口鉴权
第一步,开启注解@EnableGlobalMethodSecurity。
@SpringBootApplication @EnableGlobalMethodSecurity(prePostEnabled=true) publicclassJwtSpringSecurityDemoApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(JwtSpringSecurityDemoApplication.class,args); } }
第二部,在需要鉴权的接口上添加@PreAuthorize注解。
@RestController @RequestMapping("/test") publicclassTestController{ @GetMapping @PreAuthorize("hasAuthority('user:test')") publicStringtest(){ return"testsuccess"; } @GetMapping("/authority") @PreAuthorize("hasAuthority('admin:test')") publicStringauthority(){ return"testauthoritysuccess"; } }
到此这篇关于SpringBoot2结合Springsecurity+JWT实现微信小程序登录的文章就介绍到这了,更多相关SpringBootSpringsecurityJWT微信小程序登录内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!