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