采用前后端分离的方式,前端api接口访问,后端通过shiro权限控制。
设置跨域访问后,ajax携带cookie需要设置允许的access-orign。
可通过如下设置动态的。
// filter 中设置
if(request.getHeader("Origin").contains("mydomain.com")) {
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
}
<!-- springmv 配置设置 -->
<mvc:cors>
<mvc:mapping path="/**" allowed-origins="http://localhost:8081"/>
</mvc:cors>
现在想通过Token的方式去验证。
用户登录后返回Token即SessionId
前端:header中添加 Access-Token 值为SessionId
后端:重写DefaultWebSessionManager中的getSessionId方法。
先从Header取Token值,没有再按照默认取值:cookie->url->paramter。
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
public class AccessTokenSessionManager extends DefaultWebSessionManager {
public static final String ACCESS_TOKEN = "Access-Token";
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
if(request instanceof HttpServletRequest){
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String sessionId = httpServletRequest.getHeader(ACCESS_TOKEN);
if(sessionId!=null) {
return sessionId;
}
}
return super.getSessionId(request,response);
}
}
配置文件中指定SessionManager
<bean id="sessionManager" class="com.tg.shop.context.shiro.session.AccessTokenSessionManager" ></bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="sampleRealm"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>
还有一个问题:API返回的json值,shiro若(登录、角色、权限)验证未通过,会跳转URL而,ajax不能重定向。API接口期望返回JSON值。解决:可自定义ShiroFilter继承 AccessControlFilter,验证失败 直接response out自定义json即可。自定义的shiro需在配置文件中配置。
<bean id="login" class="com.tg.shop.context.shiro.filter.LoginFilter"/>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="filters">
<util:map>
<entry key="login" value-ref="login"></entry>
</util:map>
</property>
</bean>