开发者

SpringSecurity实现自定义登录方式

目录
  • 自定义登录
    • 1.自定义AuthenticationToken
    • 2.自定义AuthenticationFilter
    • 3.自定义Authentication编程Provider
    • 4.定义SecurityConfig配置类
  • 总结

    自定义登录

    • 定义Token
    • 定义Filter
    • 定义Provider
    • 配置类中定义登录的接口

    1.自定义AuthenticationToken

    public class EmailAuthenticationToken extends UsernamePasswordAuthenticationToken{
    
        public EmailAuthenticationToken(Object principal, Object credentials) {
            super(principal, credentials);
        }
    
        public EmailAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
            super(principal, credentials, authorities);
        }
    }
    

    2.自定义AuthenticationFilter

    public class EmailAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
        private static final String EMAIL = "email";
        private static final String EMAIL_CODE = "emailCode";
        private boolean postOnly = true;
    
    
        public EmailAuthenticationFilter(RequestMatcher requestMatcher) {
            super(requestMatcher);
        }
    
        @Override
        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
            if (this.postOnly && !request.getMethod().equals("POST")) {
                throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
            } else {
                Map<String, String> map = new ObjectMapper().readValue(request.getInputStream(), Map.class);
                String email = map.get(EMAIL);
                email = email != null ? email : "";
                email = email.trim();
                String emailCode = map.get(EMAIL_CODE);
                emailCode = emailCode != null ? emailCode : "";
                EmailAuthenticationToken emailAuthenticationToken = new EmailAuthenticationToken(email, emailCode);
                this.setDetails(request, emailAuthenticationToken);
                return this.getAuthenticationManager().authenticate(em编程ailAuthenticationToken);
            }
        }
    
        protected void setDetails(HttpServletRequest request, EmailAuthenticationToken authRequest) {
            authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
        }
    }

    3.自定义AuthenticationProvider

    public class EmailAuthenticationProvider implements AuthenticationProvider {
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            EmailAuthenticationToken emailAuthenticationToken = (EmailAuthenticationToken) authentication;
            String code = emailAuthenticationToken.getCode();
            String email = (String) emailAuthenticationToken.getPrincipal();
            if (email.equals("205564122@qq.com") && code.equals("1234")) {
                SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("wuyu");
                return new EmailAuthenticationToken(email, null, List.of(simpleGrantedAuthority));
            }
            throw new InternalAuthenticationSehttp://www.devze.comrviceException("认证失败");
        }
    
        @Override
        public boolean supports(Class<?> authenwww.devze.comtication) {
            return EmailAuthenticationToken.class.isAssignableFrom(authentication);
        }
    }
    

    4.定义SecurityConfig配置类

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Resource
        private StringRedisTemplate stringRedisTemplate;
    
        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable();
            http.cors().disable();
            http.sandroidessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
            http.authorizeHttpRequests().anyRequest().permitAll();
            http.logout().logoutSuccessHandler(logoutSuccessHandler());
    
            // 配置邮箱登录
            EmailAuthenticationFilter emailAuthenticationFilter = new EmailAuthenticationFilter(new AntPathRequestMatcher("/login/email", "POST"));
            emailAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
            emailAuthenticationFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler());
            emailAuthenticationFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
            http.addFilterBefore(emailAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
            http.authenticationProvider(new EmailAuthenticationProvider());
        }
    
        @Bean
        public AuthenticationSuccessHandler authenticationSuccessHandler() {
            return (request, response, authentication) -> {
                // 1.生成Token
                String token = UUID.randomUUID().toString();
                // 2.将Token和用户信息存入redis
                stringRedisTemplate.opsForValue().set(AuthConstants.TOKEN_PREFIX + token, jsON.toJSONString(authentication.getPrincipal()), AuthConstants.TOKEN_DURATION);
                // 3.返回Token
                response.setContentType(ResponseConstants.APPLICATION_JSON);
                PrintWriter writer = response.getWriter();
                writer.write(JSON.toJSONString(Result.success(token)));
                writer.flush();
                writer.close();
            };
        }
    
        @Bean
        public AuthenticationFailureHandler authenticationFailureHandler() {
            return (request, response, exception) -> {
                response.setContentType(ResponseConstants.APPLICATION_JSON);
                PrintWriter writer = response.getWriter();
                writer.write(JSON.toJSONString(Result.fail(exception.getMessage())));
                writer.flush();
                writer.close();
            };
        }
    
        @Bean
        public LogoutSuccessHandler logoutSuccessHandler() {
            return (request, response, authentication) -> {
                String authorization = request.getHeader(AuthConstants.AUTHORIZATION);
                authorization = authorization.replace(AuthConstants.BEARER, "");
                stringRedisTemplate.delete(AuthConstants.TOKEN_PREFIX + authorization);
                PrintWriter writer = response.getWriter();
                writer.write(JSON.toJSONString(Result.success()));
                writer.flush();
                writer.close();
            };
        }
    }
    

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜