spring session+spring security 实现用户不能重复登陆

spring session 是为了session共享  后端是几台集群。html

直接上配置:java

spring-security.xmlweb

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:security="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx             
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/task
		http://www.springframework.org/schema/task/spring-task.xsd">
		
	<security:http pattern="/packages/index/**" security="none" />
	<security:http pattern="/packages/pages/**" security="none" />
	<security:http pattern="/packages/sidebarfile.json" security="none" />
	<security:http pattern="/favicon.ico" security="none" />
	<security:http pattern="/goToLogin.html" security="none" />
	<security:http pattern="/index.html" security="none" />
	<security:http pattern="/login.json" security="none" />
	<security:http pattern="/loginPrompt.html" security="none" />
	<security:http pattern="/pseudo_login.html" security="none" />

	<security:http pattern="/mvc/dispatch" create-session="always" auto-config='true'>
		<security:intercept-url pattern="/mvc/dispatch" access="permitAll" />
		<security:csrf disabled="true" />
		<security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
        <security:session-management
            session-authentication-strategy-ref="sas" />
		
	</security:http>

	<security:authentication-manager>
		<security:authentication-provider user-service-ref="jbpUserDetailsService" />
	</security:authentication-manager>

	<security:global-method-security pre-post-annotations="enabled" />
	
	<bean id="redirectSessionInformationExpiredStrategy"
		class="org.springframework.security.web.session.SimpleRedirectSessionInformationExpiredStrategy">
		<constructor-arg name="invalidSessionUrl" value="/goLogin.html" />
	</bean>
	
	<bean id="concurrencyFilter"
        class="org.springframework.security.web.session.ConcurrentSessionFilter">
        <constructor-arg name="sessionRegistry" ref="sessionRegistry" />
   		<constructor-arg name="sessionInformationExpiredStrategy" ref="redirectSessionInformationExpiredStrategy" />
    </bean>

    <bean id="sas"
        class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
        <constructor-arg>
            <list>
                <bean
                    class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
                    <constructor-arg ref="sessionRegistry" />
                    <property name="maximumSessions" value="1" />
                </bean>
                <bean
                    class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
                </bean>
                <bean
                    class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
                    <constructor-arg ref="sessionRegistry" />
                </bean>
            </list>
        </constructor-arg>
    </bean>


	<bean id="sessionRegistry"
		class="org.springframework.session.security.SpringSessionBackedSessionRegistry">
		<constructor-arg ref="sessionRepository" />
	</bean>
</beans>

 

<bean        class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"></bean>spring

有时候会报 SessionFixation的问题 致使登陆不上去  就是 session 销毁重建的过程失败 没有建立出新的session 就tomcat集群时会报这个问题 没找到解决方式 。能够注释掉这句json

<bean        class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"></bean>后端

让他不走SessionFixation的方法就行 虽然会致使登录后 sessionid不变 可是内网的项目无所谓了。spring-mvc

 

用的security 5.0.0tomcat

以前用了废弃的方法 致使重定向 空指针 cookie

错误配置以下:session

<bean id="concurrencyFilter"
        class="org.springframework.security.web.session.ConcurrentSessionFilter">
        <constructor-arg name="sessionRegistry" ref="sessionRegistry" />
          <constructor-arg value="/goLogin.html" />
    </bean>

百度不靠谱 还得上spring-security 官网才行。 上官网一看例子 ok 调试一下源码 立马发现问题

旧配置 这个跳转的直接为null致使 500错误。

新配置直接用的response.sendRedirect(url)进行跳转。

登陆代码里还得添加手动session注册

@Autowired
	private CompositeSessionAuthenticationStrategy sas;

private void registerTokenIntoSession(User user) throws ServiceException {
		Token token = authorizationService.getUserTokenByUserId(user);
		List<GrantedAuthority> authorities = authorizationService.getAuthorities(token.getFunc());
		Authentication auth = new PreAuthenticatedAuthenticationToken(token.getUser().getAccount(), token.getUser(),
				authorities);
		auth.setAuthenticated(true);
		SecurityContextHolder.getContext().setAuthentication(auth);	
		long loginTime = System.currentTimeMillis();
		HttpSession session = servletRequest.getSession();
		session.setAttribute("tUser", token.getUser());
		session.setAttribute("loginUserCode", token.getUser().getUserCode());
		session.setAttribute("token", token);
		session.setAttribute("loginTime", loginTime);
		session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
		sas.onAuthentication(auth, servletRequest, servletResponse); //重点
		workDTO.put("token", token);
		workDTO.put("loginTime", loginTime);
	}

顺便贴一下 logout

public void logout() {
		HttpSession session = servletRequest.getSession();
		session.removeAttribute("tUser");
		session.removeAttribute("loginUserCode");
		session.removeAttribute("token");
		session.removeAttribute("loginTime");
		Cookie[] cookies = servletRequest.getCookies();
		for(Cookie cookie:cookies){
			if("userId".equals(cookie.getName())){
				Cookie dCookie=new Cookie(cookie.getName(),null);
				dCookie.setValue(null);
				dCookie.setMaxAge(0);//删除登陆 cookie
				dCookie.setPath(servletRequest.getContextPath());
				servletResponse.addCookie(dCookie);
			}
		}
		//返回新的logoutToken session标记
		CommonHelper.setLogOutToken(servletResponse,servletRequest,session,true,"logout");
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		new SecurityContextLogoutHandler().logout(ActionContext.getContext().getServletRequest(),
				ActionContext.getContext().getServletResponse(), auth);
		
	}
相关文章
相关标签/搜索