SpringSecurity實現(xiàn)自定義登錄方式
更新時間:2024年09月18日 10:06:26 作者:勿語&
本文介紹自定義登錄流程,包括自定義AuthenticationToken、AuthenticationFilter、AuthenticationProvider以及SecurityConfig配置類,詳細解析了認證流程的實現(xiàn),為開發(fā)人員提供了具體的實施指導(dǎo)和參考
自定義登錄
- 定義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();
};
}
}
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java 中序列化與readResolve()方法的實例詳解
這篇文章主要介紹了java 中序列化與readResolve()方法的實例詳解的相關(guān)資料,這里提供實例幫助大家理解這部分知識,需要的朋友可以參考下2017-08-08
spring 或者spring boot 調(diào)整bean加載順序的方式
這篇文章主要介紹了spring 或者spring boot 調(diào)整bean加載順序的方式,本文通過實例代碼講解三種調(diào)整類加載順序的方式,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03
RestTemplate響應(yīng)中如何獲取輸入流InputStream
這篇文章主要介紹了RestTemplate響應(yīng)中如何獲取輸入流InputStream問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
詳解Java MyBatis 插入數(shù)據(jù)庫返回主鍵
這篇文章主要介紹了詳解Java MyBatis 插入數(shù)據(jù)庫返回主鍵,有興趣的可以了解一下。2017-01-01

