前后的分离配置shrio

已拦截跨源请求:同源策略禁止读取位于 http://localhost/payment/page 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin’)。
已拦截跨源请求:同源策略禁止读取位于 http://localhost/payment/page 的远程资源。(原因:CORS 请求未能成功)。
Error: Network Error

原因:前后端分离项目中,ajax请求没有携带cookie,所以后台无法通过cookie获取到SESSIONID,从而无法获取到session对象。而shiro的认证与授权都是通过session实现的

解决:
1.前后端需要建立会话机制
通过token的机制建立前端和后端的会话管理机制
1)登录成功后返回token,并以后每次ajax请求都要携带token

contrller
1.登录成功加上

//获取到登录成功存储到系统上下文中的用户名密码,强转成User类型
User principal = (User)subject.getPrincipal();
//将密码设置为null再传给前台
principal.setPassword(null);
//定义一个map集合拿来存储需要返回的值
HashMap<String,Object> map = new HashMap<>();
//将登录成功的对象存入map
map.put("user", principal);
//将sessionId存储到map
map.put("token", subject.getSession().getId());
//将map存到封装好的返回格式工具类中
ajaxResult.setResultObj(map);

2.前端main.js


//发送请求之前 拦截 把token设置到请求头里面
axios.interceptors.request.use(config => {
    //获取前台session里面的token
    if (sessionStorage.getItem('token')) {
        // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
        config.headers['X-TOKEN'] = sessionStorage.getItem('token')
    }
    console.debug('config',config)
    return config
}, error => {
    // Do something with request error
    Promise.reject(error)
});

3.传统结构项目中,shiro从cookie中读取sessionId以此来维持会话,在前后端分离的项目中,因此需要重写shiro获取sessionId的方式。 * 自定义SessionManager类继承DefaultWebSessionManager类,重写getSessionId方法

public class crmSessionManager extends DefaultWebSessionManager {
    private static final String AUTHORIZATION = "X-TOKEN";

    private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";

    @Override
    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        //取到jessionid
        String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
        HttpServletRequest request1 = (HttpServletRequest) request;
        //如果请求头中有 X-TOKEN 则其值为sessionId
        if (!StringUtils.isEmpty(id)) {
            System.out.println(id+"jjjjjjjjj"+request1.getRequestURI()+request1.getMethod());
            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;
        } else {
            //否则按默认规则从cookie取sessionId
            return super.getSessionId(request, response);
        }
    }
}
	

3.1注入重写方法获取sessionId的对象

<bean id="sessionManager" class="com.edu.zhy.crm.crmSessionManager"/>
<!--shiro的核心对象 realm-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!--配置realm-->
    <property name="realm" ref="authRealm"/>
    <!-- 调用自己获取sessionid的方法-->
    <property name="sessionManager" ref="sessionManager"></property>
</bean>

4.自定义shrio身份认证过滤器 继承FormAuthenticationFilter

/*
* 自定义身份认证过滤器
* */
public class MyAuthenticationFilter extends FormAuthenticationFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        //如果是OPTIONS请求,直接放行
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String method = httpServletRequest.getMethod();
        System.out.println(method);
        if("OPTIONS".equalsIgnoreCase(method)){
            return true;
        }
        return super.isAccessAllowed(request, response, mappedValue);
    }

配置上自己重写的过滤器

<!-- 配置过滤器-->
bean注入自己重写过滤器
<bean id="authFilter" class="com.edu.zhy.crm.shrio.filter.MyAuthFilter"></bean>

<!--shiro的过滤器配置 web.xml的代理过滤器名称一样-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/s/login"/>
    <property name="successUrl" value="/s/index"/>
    <property name="unauthorizedUrl" value="/s/unauthorized"/>
    <!--使用自定义过滤器-->
    <property name="filters">
        <map>
            <entry key="authFilter" value-ref="authFilter"></entry>
        </map>
    </property>
    <property name="filterChainDefinitions">
        <value>
            /login = anon
            /** /**= myAuthc**/
        </value>
    </property>
</bean>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值