web.xml文件配置
第一点,注意配置版本为3.0版本,
Servlet3.0规范中的<tracking-mode>允许你定义JSESSIONID是存储在cookie中还是URL参数中。如果会话ID存储在URL中,那么它可能会被无意的存储在多个地方,包括浏览器历史、代理服务器日志、引用日志和web日志等。暴露了会话ID使得网站被session劫持***的几率大增。然而,确保JSESSIONID被存储在cookie中
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <session-config> <tracking-mode>COOKIE</tracking-mode> </session-config>
===============================我是分割线====================================
在使用shiro之后,shiro的重定向跳转,默认是带有JSESSIONID的
附上ShiroHttpServletResponse源码
@Override public String encodeRedirectURL(String url){ /** 下面是ShiroHttpServletResponse源码,重写shiro的encodeRedirectURL方法,把url路径里的JSESSIONID去掉 **/ if (isEncodeable(toAbsolute(url))) { return toEncoded(url, request.getSession().getId()); } else { return url; } return url; }
上面是此类第一个方法,下面是此类第二个方法
@Override protected String toEncoded(String url, String sessionId) { if ((url == null) || (sessionId == null)) return (url); String path = url; String query = ""; String anchor = ""; int question = url.indexOf('?'); if (question >= 0) { path = url.substring(0, question); query = url.substring(question); } int pound = path.indexOf('#'); if (pound >= 0) { anchor = path.substring(pound); path = path.substring(0, pound); } StringBuilder sb = new StringBuilder(path); /** 下面是ShiroHttpServletResponse源码,重写shiro的toEncoded方法使其不拼接JSESSIONID **/ if (sb.length() > 0) { // session id param can't be first. sb.append(";"); sb.append(DEFAULT_SESSION_ID_PARAMETER_NAME); sb.append("="); sb.append(sessionId); } sb.append(anchor); sb.append(query); return (sb.toString()); }
由此我们知道shiro第一次访问重定向的时候会带有JSESSIONID=xxxxxxxxxxxx
那么解决方案如下:
新建MyShiroHttpServletResponse继承ShiroHttpServletResponse
重写其方法encodeRedirectURL和toEncoded
package com.uu.back.util; import org.apache.shiro.web.servlet.ShiroHttpServletRequest; import org.apache.shiro.web.servlet.ShiroHttpServletResponse; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletResponse; /** * Created by Alex on 2016/9/26. */ public class MyShiroHttpServletResponse extends ShiroHttpServletResponse { public MyShiroHttpServletResponse(HttpServletResponse wrapped, ServletContext context, ShiroHttpServletRequest request) { super(wrapped, context, request); } @Override public String encodeRedirectURL(String url){ /** 下面是ShiroHttpServletResponse源码,重写shiro的encodeRedirectURL方法,把url路径里的JSESSIONID去掉 **/ // if (isEncodeable(toAbsolute(url))) { // return toEncoded(url, request.getSession().getId()); // } else { // return url; // } return url; } @Override protected String toEncoded(String url, String sessionId) { if ((url == null) || (sessionId == null)) return (url); String path = url; String query = ""; String anchor = ""; int question = url.indexOf('?'); if (question >= 0) { path = url.substring(0, question); query = url.substring(question); } int pound = path.indexOf('#'); if (pound >= 0) { anchor = path.substring(pound); path = path.substring(0, pound); } StringBuilder sb = new StringBuilder(path); /** 下面是ShiroHttpServletResponse源码,重写shiro的toEncoded方法使其不拼接JSESSIONID **/ // if (sb.length() > 0) { // session id param can't be first. // sb.append(";"); // sb.append(DEFAULT_SESSION_ID_PARAMETER_NAME); // sb.append("="); // sb.append(sessionId); // } sb.append(anchor); sb.append(query); return (sb.toString()); } }
新建MySpringShiroFilter继承AbstractShiroFilter
package com.uu.back.util; import org.apache.shiro.web.filter.mgt.FilterChainResolver; import org.apache.shiro.web.mgt.WebSecurityManager; import org.apache.shiro.web.servlet.AbstractShiroFilter; import org.apache.shiro.web.servlet.ShiroHttpServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; /** * Created by Alex on 2016/9/26. */ public class MySpringShiroFilter extends AbstractShiroFilter { protected MySpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) { super(); if (webSecurityManager == null) { throw new IllegalArgumentException("WebSecurityManager property cannot be null."); } setSecurityManager(webSecurityManager); if (resolver != null) { setFilterChainResolver(resolver); } } @Override protected ServletResponse wrapServletResponse(HttpServletResponse orig, ShiroHttpServletRequest request) { return new MyShiroHttpServletResponse(orig, getServletContext(), request); } }
新建MyShiroFilterFactoryBean继承ShiroFilterFactoryBean
package com.uu.back.util; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.filter.mgt.FilterChainManager; import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver; import org.apache.shiro.web.mgt.WebSecurityManager; import org.apache.shiro.web.servlet.AbstractShiroFilter; import org.springframework.beans.factory.BeanInitializationException; /** * Created by Alex on 2016/9/26. */ public class MyShiroFilterFactoryBean extends ShiroFilterFactoryBean { @Override public Class getObjectType() { return MySpringShiroFilter.class; } @Override protected AbstractShiroFilter createInstance() throws Exception { SecurityManager securityManager = getSecurityManager(); if (securityManager == null) { String msg = "SecurityManager property must be set."; throw new BeanInitializationException(msg); } if (!(securityManager instanceof WebSecurityManager)) { String msg = "The security manager does not implement the WebSecurityManager interface."; throw new BeanInitializationException(msg); } FilterChainManager manager = createFilterChainManager(); PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver(); chainResolver.setFilterChainManager(manager); return new MySpringShiroFilter((WebSecurityManager) securityManager, chainResolver); } }
修改shiro的配置文件:
注释掉的就是原有的,现在我们不用原有的,使用我们自己写好的
<!--<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">--> <bean id="shiroFilter" class="com.uu.back.util.MyShiroFilterFactoryBean"> /** **/ </bean>
重启,访问:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。