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); }