SpringBoot整合SpringSecurity,SESSION 并发管理,同账号只允许登录一次
来源:互联网 发布:天池大数据竞赛 个人 编辑:程序博客网 时间:2024/05/17 21:55
重写了UsernamePasswordAuthenticationFilter,里面继承AbstractAuthenticationProcessingFilter,这个类里面的session认证策略,是一个空方法,貌似RememberMe也是.
public abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBean implements ApplicationEventPublisherAware, MessageSourceAware { protected ApplicationEventPublisher eventPublisher; protected AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource(); private AuthenticationManager authenticationManager; protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor(); private RememberMeServices rememberMeServices = new NullRememberMeServices(); private RequestMatcher requiresAuthenticationRequestMatcher; private boolean continueChainBeforeSuccessfulAuthentication = false; private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy(); private boolean allowSessionCreation = true; private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
NullAuthenticatedSessionStrategy 源码
public final class NullAuthenticatedSessionStrategy implements SessionAuthenticationStrategy { public NullAuthenticatedSessionStrategy() { } public void onAuthentication(Authentication authentication, HttpServletRequest request, HttpServletResponse response) { }}
所以必须自己配置一个session验证策略,以及配置并发控制.红字为关键
WebSecurityConfigurerAdapter
/** * Created by ZhenWeiLai on on 2016-10-16. * <p> * 三种方法级权限控制 * <p> * 1.securedEnabled: Spring Security’s native annotation * 2.jsr250Enabled: standards-based and allow simple role-based constraints * 3.prePostEnabled: expression-based */@EnableWebSecurity//@EnableGlobalMethodSecurity(prePostEnabled = true)public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Resource private UserDetailsService userDetailsService; @Resource private FilterInvocationSecurityMetadataSource securityMetadataSource; @Resource private SessionRegistry sessionRegistry; @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/assets/**"); web.ignoring().antMatchers("/components/**"); web.ignoring().antMatchers("/css/**"); web.ignoring().antMatchers("/images/**"); web.ignoring().antMatchers("/js/**"); web.ignoring().antMatchers("/mustache/**"); web.ignoring().antMatchers("/favicon.ico"); //注册地址不拦截// web.ignoring().antMatchers("/base/invoice/userinfo/u/reg");// web.ignoring().antMatchers("/**"); } @Override protected void configure(HttpSecurity http) throws Exception { //解决不允许显示在iframe的问题 http.headers().frameOptions().disable(); http.addFilterAt(usernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); //session并发控制过滤器 http.addFilterAt(new ConcurrentSessionFilter(sessionRegistry,sessionInformationExpiredStrategy()),ConcurrentSessionFilter.class); //自定义过滤器 //在适当的地方加入 http.addFilterAt(filterSecurityInterceptor(securityMetadataSource, accessDecisionManager(), authenticationManagerBean()), FilterSecurityInterceptor.class); http.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")).and().logout().logoutUrl("/logout").logoutSuccessUrl("/login").permitAll().and().exceptionHandling().accessDeniedPage("/accessDenied"); http.authorizeRequests().anyRequest().fullyAuthenticated(); // 关闭csrf http.csrf().disable(); /** * 以下配置无效 */ //session管理 //session失效后跳转// http.sessionManagement().invalidSessionUrl("/login");// //只允许一个用户登录,如果同一个账户两次登录,那么第一个账户将被踢下线,跳转到登录页面// http.sessionManagement().maximumSessions(1).expiredUrl("/login"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 自定义UserDetailsService,设置加密算法 auth.userDetailsService(userDetailsService);//.passwordEncoder(passwordEncoder()) //不删除凭据,以便记住用户 auth.eraseCredentials(false); } //session失效跳转 private SessionInformationExpiredStrategy sessionInformationExpiredStrategy() { return new SimpleRedirectSessionInformationExpiredStrategy("/login"); } @Bean public SessionRegistry sessionRegistry() { return new SessionRegistryImpl(); } //SpringSecurity内置的session监听器 @Bean public HttpSessionEventPublisher httpSessionEventPublisher() { return new HttpSessionEventPublisher(); } private UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() throws Exception { UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter = new CuzUsernamePasswordAuthenticationFilter(); usernamePasswordAuthenticationFilter.setPostOnly(true); usernamePasswordAuthenticationFilter.setAuthenticationManager(this.authenticationManager()); usernamePasswordAuthenticationFilter.setUsernameParameter("name_key"); usernamePasswordAuthenticationFilter.setPasswordParameter("pwd_key"); usernamePasswordAuthenticationFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/checkLogin", "POST")); usernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler()); usernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler()); //session并发控制,因为默认的并发控制方法是空方法.这里必须自己配置一个 usernamePasswordAuthenticationFilter.setSessionAuthenticationStrategy(new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry)); return usernamePasswordAuthenticationFilter; }// @Bean// public LoggerListener loggerListener() {// System.out.println("org.springframework.security.authentication.event.LoggerListener");// return new LoggerListener();// }//// @Bean// public org.springframework.security.access.event.LoggerListener eventLoggerListener() {// System.out.println("org.springframework.security.access.event.LoggerListener");// return new org.springframework.security.access.event.LoggerListener();// } /** * 投票器 */ private AbstractAccessDecisionManager accessDecisionManager() { List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList(); decisionVoters.add(new AuthenticatedVoter()); decisionVoters.add(new RoleVoter());//角色投票器,默认前缀为ROLE_ RoleVoter AuthVoter = new RoleVoter(); AuthVoter.setRolePrefix("AUTH_");//特殊权限投票器,修改前缀为AUTH_ decisionVoters.add(AuthVoter); AbstractAccessDecisionManager accessDecisionManager = new AffirmativeBased(decisionVoters); return accessDecisionManager; } @Override public AuthenticationManager authenticationManagerBean() { AuthenticationManager authenticationManager = null; try { authenticationManager = super.authenticationManagerBean(); } catch (Exception e) { e.printStackTrace(); } return authenticationManager; } /** * 验证异常处理器 * * @return */ private SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler() { return new SimpleUrlAuthenticationFailureHandler("/getLoginError"); }// /**// * 表达式控制器// *// * @return// */// private DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {// DefaultWebSecurityExpressionHandler webSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();// return webSecurityExpressionHandler;// }// /**// * 表达式投票器// *// * @return// */// private WebExpressionVoter webExpressionVoter() {// WebExpressionVoter webExpressionVoter = new WebExpressionVoter();// webExpressionVoter.setExpressionHandler(webSecurityExpressionHandler());// return webExpressionVoter;// } // Code5 官方推荐加密算法// @Bean("passwordEncoder")// public BCryptPasswordEncoder passwordEncoder() {// BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();// return bCryptPasswordEncoder;// }// // Code3---------------------------------------------- /** * 登录成功后跳转 * 如果需要根据不同的角色做不同的跳转处理,那么继承AuthenticationSuccessHandler重写方法 * * @return */ private SimpleUrlAuthenticationSuccessHandler authenticationSuccessHandler() { return new SimpleUrlAuthenticationSuccessHandler("/loginSuccess"); } /** * Created by ZhenWeiLai on on 2016-10-16. */ private FilterSecurityInterceptor filterSecurityInterceptor(FilterInvocationSecurityMetadataSource securityMetadataSource, AccessDecisionManager accessDecisionManager, AuthenticationManager authenticationManager) { FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor(); filterSecurityInterceptor.setSecurityMetadataSource(securityMetadataSource); filterSecurityInterceptor.setAccessDecisionManager(accessDecisionManager); filterSecurityInterceptor.setAuthenticationManager(authenticationManager); return filterSecurityInterceptor; }}
继承UsernamePasswordAuthenticationFilter ,注入SessionRegistry ,当用户登录验证成功后注册session
/** * Created by ZhenWeiLai on 2017/6/2. */public class CuzUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private boolean postOnly = true; @Resource private SessionRegistry sessionRegistry; @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if(this.postOnly && !request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } else { String username = this.obtainUsername(request); String password = this.obtainPassword(request); if(username == null) { username = ""; } if(password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); //用户名密码验证通过后,注册session sessionRegistry.registerNewSession(request.getSession().getId(),authRequest.getPrincipal()); this.setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } }}
重写用户实体类的比较方法.
/** * 重写比较方法,SpringSecurity根据用户名来比较是否同一个用户 */ @Override public boolean equals(Object o){ if(o.toString().equals(this.username)) return true; return false; } @Override public int hashCode(){ return username.hashCode(); } @Override public String toString() { return this.username;
阅读全文
0 0
- SpringBoot整合SpringSecurity,SESSION 并发管理,同账号只允许登录一次
- Spring boot +Spring security4 config 配置同账号登录只允许一个在线
- springBoot+mybatis+springsecurity整合!
- Spring Boot 同一账号只允许一次登陆
- springboot(十四):springboot整合shiro-登录认证和权限管理
- springboot(十四):springboot整合shiro-登录认证和权限管理
- springboot(十四):springboot整合shiro-登录认证和权限管理
- springboot(十四):springboot整合shiro-登录认证和权限管理
- springboot(十四):springboot整合shiro-登录认证和权限管理
- springboot(十四):springboot整合shiro-登录认证和权限管理
- 程序只允许运行一次
- 如何创建一个只允许使用sftp登录且只能访问特定目录的账号
- 多相同用户或多浏览器中仅仅允许登录一次系统问题?
- springboot+springSecurity+mybatis实现权限管理
- spring security 3.0的控制一个帐号只允许一次登录
- springboot整合shiro-登录认证和权限管理
- SpringSecurity(六):Session(集群)管理和Logout
- Springboot 整合日志管理
- TextView+Spinner的使用
- 反转链表
- 端口号及URG和PSH的区别
- 事物的特性
- c++入门
- SpringBoot整合SpringSecurity,SESSION 并发管理,同账号只允许登录一次
- 浏览器缓存机制
- 机器人程序设计——之如何正确入门ROS | 硬创公开课
- hdoj1001 Sum Problem(细心点)
- Asp.Net笔记目录
- MAC 下的SVN客户端 Versions、SmartSVN、Cornerstone
- linux基础入门之groupdel命令
- python函数学习--函数的四种返回值形式
- Bootstrap Modal的“上一步”,“下一步”切换功能的实现