设置shiro认证和授权失败返回json而不是重定向

在使用shiro时,一般对未认证或未授权的请求统一过滤并做出响应,大体有以下配置:

<!-- 未认证时返回的页面(被authc user logout 等认证拦截器拦截后)访问的url -->
<property name="loginUrl" value="/user/unAuthenticated.do"/> 
<!-- 未授权时返回的页面(被roles 等授权拦截器拦截后)访问的url -->
<property name="unauthorizedUrl" value="/user/unAuthorized.do"/> 

或者在java原始配置中:

shiroFilterFactoryBean.setLoginUrl("/user/unAuthenticated.do");
shiroFilterFactoryBean.setUnauthorizedUrl("/user/unAuthorized.do");

但默认情况下,拦截器拦截后,是重定向到相应的url。这就造成一个问题,在前后端分离的项目中,前端无法对为认证或未授权的页面做出处理。而理想状态下是应该shiro对未认证或未授权的url拦截后,返回json,前端通过json再做出相应的提示或跳转页面。这就需要后端使用shiro时要 自 定 义 过 滤 器 \color{red}{自定义过滤器}

默认情况下,几个常用的拦截器总结如下:

有关认证的拦截器:

拦截器名 默认拦截器类 说明
authc FormAuthenticationFilter 需要认证才可以访问
主要属性:
loginUrl:登录的url,默认login.jsp,如果被这个过滤器拦截后,会重定向这个url
successUrl:登录成功后重定向的url
user UserFilter 需要认证或记住我才可以访问
logout LogoutFilter 退出url
主要属性:
redirectUrl:退出后重定向的url,默认"/“
如设置”/logout=logout"后,当访问/logout会被拦截,执行退出,再重定向到redirectUrl
anon AnonymousFilter 不拦截,总会放行

有关授权的拦截器:

拦截器名 默认拦截器类 说明
roles RolesAuthorizationFilter 验证当前用户是否拥有所有角色
主要属性:
unauthorizedUrl:未授权重定向的url
loginUrl:登录页面的url
如配置"/admin/**=roles[user,admin]"则访问/admin/时,如果该用户没有同事拥有user和admin两种角色,则重定向到unauthorizedUrl
perms PermissionsAuthorizationFilter 验证当前用户是否拥有所有权限,主要属性和roles一致

换句话说,默认情况下,当shiro发生拦截行为时,会调用相应的拦截器重定向到相应的url。因为,如果希望它不发生重定向,而是直接返回json的话,需要我们自定义拦截器并使用自定义的拦截器。

以下对两个常用的拦截做示例(authc和roles)

在此之前,关注这几个拦截类的共同父类AccessControlFilter(eclipse中使用ctrl+T可以查看继承树),其中的onPreHandle方法:

public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
   
        return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
    }

过滤的原则有两个决定,isAccessAllowed即判断请求的url是否合法,onAccessDenied即对不合法的请求的拦截后执行的逻辑。我们想要更改的是令shiro拦截后返回json,所以仅需改onAccessDenied即可。

对未认证页面的过滤

从上面表格中可以看出,authc使用的是FormAuthenticationFilter拦截器,查看onAccessDenied方法的源码如下(eclipse使用快捷键ctrl+shift+H可以搜索类):

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
   
    // 先判断访问的是否是登录页面,如果是则放行    
    if (isLoginRequest(request, response)) {
   
            if (isLoginSubmission(request
  • 14
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值