SpringSecurity实现自定义登录方式
更新时间:2024年09月18日 10:06:26 作者:勿语&
本文介绍自定义登录流程,包括自定义AuthenticationToken、AuthenticationFilter、AuthenticationProvider以及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(emailAuthenticationToken); } } 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 InternalAuthenticationServiceException("认证失败"); } @Override public boolean supports(Class<?> authentication) { 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.sessionManagement().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(); }; } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
SpringBoot Knife4j框架&Knife4j的显示内容的配置方式
Knife4j框架是基于Swagger2开发的在线API文档生成工具,主要功能包括自动生成API文档、接口文档展示、接口测试工具、接口权限控制和在线调试,该框架支持通过注解自动生成详细的接口文档,开发者可以直接在文档界面进行接口测试和调试2024-09-09使用AOP拦截Controller获取@PathVariable注解传入的参数
这篇文章主要介绍了使用AOP拦截Controller获取@PathVariable注解传入的参数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-08-08springboot 正确的在异步线程中使用request的示例代码
这篇文章主要介绍了springboot中如何正确的在异步线程中使用request,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2022-07-07Java concurrency之Condition条件_动力节点Java学院整理
Condition的作用是对锁进行更精确的控制。下面通过本文给大家分享Java concurrency之Condition条件的相关知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧2017-06-06
最新评论