1、导入jar包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>2.0.1.RELEASE</version> <scope>compile</scope> </dependency>
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId> <version>5.1.5.RELEASE</version> </dependency>
2、配置SecurityConfig
@EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AuthenticationSuccessHandler authenticationSuccessHandler; @Autowired private AuthenticationFailureHandler authenticationFailureHandler; @Autowired private LogoutSuccessHandler logoutSuccessHandler; @Autowired private AuthenticationEntryPoint authenticationEntryPoint; @Autowired private UserDetailsService userDetailsService; @Autowired private TokenFilter tokenFilter; @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); // 基于token,所以不需要session http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.authorizeRequests() .antMatchers("/login/**") // 配置不需要拦截的请求url .permitAll().anyRequest().authenticated(); http.formLogin().loginPage("/login.html").loginProcessingUrl("/user/login") .successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler).and() .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint); http.logout().logoutUrl("/user/logout").logoutSuccessHandler(logoutSuccessHandler); // 解决不允许显示在iframe的问题 http.headers().frameOptions().disable(); http.headers().cacheControl(); http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(new PasswordEncoder() { @Override public String encode(CharSequence charSequence) { return MD5.sign((String)charSequence); } @Override public boolean matches(CharSequence charSequence, String s) { return s.equals(MD5.sign((String)charSequence)); } }); }
3、配置SecurityHandlerConfig
@Configuration public class SecurityHandlerConfig { /** * 登陆成功,返回Token * * @return */ @Bean public AuthenticationSuccessHandler loginSuccessHandler() { return new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { } }; } /** * 登陆失败 * * @return */ @Bean public AuthenticationFailureHandler loginFailureHandler() { return new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { String msg = null; if (exception instanceof BadCredentialsException) { msg = "密码错误"; } else { msg = exception.getMessage(); } // ResponseInfo info = new ResponseInfo(HttpStatus.UNAUTHORIZED.value() + "", msg); Map<String, Object> data = new HashMap<>(); data.put("loginType", 5); data.put("loginMsg", msg); ResponseUtil.responseJson(response, HttpStatus.OK.value(), Result.fail()); } }; } /** * 未登录,返回401 * * @return */ @Bean public AuthenticationEntryPoint authenticationEntryPoint() { return new AuthenticationEntryPoint() { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { String url = request.getRequestURI(); if (url.endsWith(".html")) { response.sendRedirect("/"); } else { Map map = new HashMap(); map.put("code",HttpStatus.UNAUTHORIZED.value() + ""); map.put("messageText","请先登录"); ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), map); } } }; } /** * 退出处理 * * @return */ @Bean public LogoutSuccessHandler logoutSussHandler() { return new LogoutSuccessHandler() { @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { Map map = new HashMap(); map.put("code",HttpStatus.OK.value() + ""); map.put("messageText","退出成功"); ResponseUtil.responseJson(response, HttpStatus.OK.value(), map); } }; }
4、配置拦截器 TokenFilter
@Component public class TokenFilter extends OncePerRequestFilter { public static final String TOKEN_KEY = "sxzqfwentToken"; @Autowired private TokenService tokenService; @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { String token = getToken(httpServletRequest); if (!StringUtils.isEmpty(token)) { LoginUser loginUser = tokenService.getLoginUser(token); if (loginUser != null) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginUser, null, null); SecurityContextHolder.getContext().setAuthentication(authentication); } } filterChain.doFilter(httpServletRequest, httpServletResponse); } /** * 根据参数或者header获取token * * @param request * @return */ public static String getToken(HttpServletRequest request) { String token = request.getParameter(TOKEN_KEY); if (StringUtils.isEmpty(token)) { token = request.getHeader(TOKEN_KEY); } if (StringUtils.isEmpty(token)) { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if (TOKEN_KEY.equals(cookie.getName())) { token = cookie.getValue(); break; } } } } return token; }
以上就是简单的实现逻辑,有错误欢迎纠正。