zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Spring Security 多登录实现详解编程语言

Spring编程语言 实现 详解 登录 Security
2023-06-13 09:20:22 时间

需要先增加一个自定义的Filter去继承 UsernamePasswordAuthenticationFilter 或者 AbstractAuthenticationProcessingFilter

然后在自定义的Filter里面指定登录的Url . 设置过滤器的时候,必须为过滤器指定一个 authenticationManager ,并且初始化构造函数的时候,要传入该manager.

再编写一个Provider , 把自定义的UserDetailService传给该provider.

具体实现过程如下:

添加配置:

@Override 

 protected void configure(AuthenticationManagerBuilder auth) {

 //增加自定义的UserDetailService 

 userDetailsAuthenticationProvider.setUserDetailsService(userDetailsService); 

 //设置一个Provider 

 auth.authenticationProvider(userDetailsAuthenticationProvider); 

}

关键配置:

@Override 

protected void configure(HttpSecurity http) throws Exception { 

 //手动实现的权限验证管理器 

 movieAuthorizeConfigProviderManager.configure(http.authorizeRequests()); 

 //添加前台登录验证过滤器与userDetailService,不同的登录处理URL需要在Filter里面指定 

 UserAuthenticationFilter userAuthenticationFilter = new UserAuthenticationFilter(); 

 //每个Filter必须指定一个authenticationManager 

 userAuthenticationFilter.setAuthenticationManager(authenticationManager()); 

 //设置登录成功处理事件 

 userAuthenticationFilter.setAuthenticationSuccessHandler(movieAuthenticationSuccessHandler); 

 //设置登录失败处理事件 

 userAuthenticationFilter.setAuthenticationFailureHandler(movieAuthenticationFailureHandler); 

 http.addFilterBefore(userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

}

完整配置:

Spring Security 多登录实现详解编程语言

自定义过滤器:

public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 

public static final String POST =  POST  

 public MyAuthenticationFilter() {

 this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher( /user/login/check ,  POST )); 

 this.setAuthenticationManager(getAuthenticationManager()); 

 } 

 @Override 

 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 

 if (!request.getMethod().equals(POST)) { 

 throw new AuthenticationServiceException(  Authentication method not supported:   + request.getMethod()); 

 } 

 String username = obtainUsername(request); 

 String password = obtainPassword(request); 

 if (username == null) { 

 username =   

 } 

 if (password == null) { 

 password =   

 } 

 username = username.trim(); 

 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); 

 // Allow subclasses to set the  details  property 

 setDetails(request, authRequest); 

 return this.getAuthenticationManager().authenticate(authRequest); 

 } 

}

Provider:

@Component 

public class UserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { 

private volatile String userNotFoundEncodedPassword; 

private static final String USER_NOT_FOUND_PASSWORD =  userNotFoundPassword  

 @Autowired 

 private PasswordEncoder passwordEncoder; 

 private UserDetailsService userDetailsService; 

 

 @Override 

 protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { 

 if (authentication.getCredentials() == null) { 

 throw new BadCredentialsException(messages.getMessage(  AbstractUserDetailsAuthenticationProvider.badCredentials ,  Bad credentials )); 

 } 

 String presentedPassword = authentication.getCredentials().toString(); 

 if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) { 

 logger.debug( Authentication failed: password does not match stored value  

 throw new BadCredentialsException(messages.getMessage(  AbstractUserDetailsAuthenticationProvider.badCredentials ,  Bad credentials )); 

 } 

 } 

 

 @Override 

 protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { 

 prepareTimingAttackProtection(); 

 try { 

 UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username); 

 if (loadedUser == null) { 

 throw new InternalAuthenticationServiceException(  UserDetailsService returned null, which is an interface contract violation  

 } 

 return loadedUser; 

 } catch (UsernameNotFoundException ex) { 

 mitigateAgainstTimingAttack(authentication); 

 throw ex; 

 } catch (InternalAuthenticationServiceException ex) { 

 throw ex; 

 } catch (Exception ex) { 

 throw new InternalAuthenticationServiceException(ex.getMessage(), ex); 

 } 

 } 

 private void prepareTimingAttackProtection() { 

 if (this.userNotFoundEncodedPassword == null) { 

 this.userNotFoundEncodedPassword = this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD); 

 } 

 } 

 private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken authentication) { 

 if (authentication.getCredentials() != null) { 

 String presentedPassword = authentication.getCredentials().toString(); 

 this.passwordEncoder.matches(presentedPassword, this.userNotFoundEncodedPassword); 

 } 

 } 

 

 public UserDetailsService getUserDetailsService() { 

 return userDetailsService; 

 } 

 public void setUserDetailsService(UserDetailsService userDetailsService) { 

 this.userDetailsService = userDetailsService; 

 } 

}

UserDetailService:

@Component 

@Slf4j 

@Qualifier( normalUserDetailService ) 

public class UserDetailServiceImpl implements UserDetailsService { 

 private final IUserDao userDao; 

 public UserDetailServiceImpl(IUserDao userDao) { 

 this.userDao = userDao; 

 } 

 

 @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 

 club.cearnach.movie.entity.User user = userDao.findByAccount(username) 

 .orElseThrow(() -  new UsernameNotFoundException( 找不到指定的用户 )); 

 List GrantedAuthority  authorities = AuthorityUtils 

 .commaSeparatedStringToAuthorityList( 

 MovieSecurityConstants.ROLE_PREFIX.concat(user.getRole().getName())); 

 return new User(user.getAccount(), user.getPassword(), authorities); 

 } 

}

第二个UserDetailService的实现:

@Component 

@Qualifier( adminDetailService ) 

public class AdminUserDetailServiceImpl implements UserDetailsService { 

 private final IAdminService adminService; 

 public AdminUserDetailServiceImpl(IAdminService adminService) { 

 this.adminService = adminService; 

 } 

 

 @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 

 Admin admin = adminService.findByAccount(username) 

 .orElseThrow(() -  new UsernameNotFoundException(AdminException.ADMIN_CAN_NOT_FOUNT)); 

 List GrantedAuthority  authorities = AuthorityUtils.commaSeparatedStringToAuthorityList( 

 MovieSecurityConstants.ROLE_PREFIX.concat(admin.getRole().getName())); 

 return new User(admin.getAccount(), admin.getPassword(), authorities); 

 } 

}

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/7482.html

cjava