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);
		
	}
相關文章
相關標籤/搜索