Spring Security 多登录接口实现
2018-06-18 00:45:13来源:未知 阅读 ()
需要先增加一个自定义的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);
}
完整配置:
自定义过滤器:
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); } }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash