shiro 前后端分离解决跨域 以及 自定义ShiroSessionManager 校验请求头的JsessionId
1.解决跨域
import org.apache.shiro.web.servlet.OncePerRequestFilter;
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CORSFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
HttpServletResponse res = (HttpServletResponse) servletResponse;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "*");
filterChain.doFilter(servletRequest, servletResponse);
}
2.自定义 ShiroSessionManager
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;
import java.util.Enumeration;
/**
* 自定义session获取方式
* 采用ajax请求头authToken携带sessionId的方式
**/
public class ShiroSessionManager extends DefaultWebSessionManager {
private static final String AUTHORIZATION = "authToken";
private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
public ShiroSessionManager() {
super();
}
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
Enumeration<String> headers = WebUtils.toHttp(request).getHeaderNames();
String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
if (StringUtils.isEmpty(id)) {
//如果没有携带id参数则按照父类的方式在cookie进行获取
// System.out.println("super:"+super.getSessionId(request, response));
return super.getSessionId(request, response);
} else {
//如果请求头中有 authToken 则其值为sessionId
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
return id;
}
}
3.注入bean
@Bean(name="sessionManager")
public DefaultWebSessionManager defaultWebSessionManager() {
ShiroSessionManager shiroSessionManager = new ShiroSessionManager();
shiroSessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
return shiroSessionManager;
}
//权限管理,配置主要是Realm的管理认证
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(shiroRealm());
securityManager.setSessionManager(defaultWebSessionManager());
return securityManager;
}
/**
* 自定义身份认证 realm;
* <p>
*/
@Bean
public ShiroRealm shiroRealm() {
ShiroRealm shiroRealm = new ShiroRealm();
//指定自定义密码匹配逻辑
shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
shiroRealm.setCachingEnabled(false);
return shiroRealm;
}
记录一波