Shiro 集成 Spring 之过滤器

在之前Shiro 集成 Spring 这一章中我们简单使用了 shiroFilter
中的 filterChainDefinitions
来做 认证
授权
的拦截,其实还有许多过滤器,可以做各种各样的拦截,并且 Shiro 还提供了接口来让我们自定义过滤器。

身份认证相关

anon

例: /admins/**=anon
,没有参数,表示可以匿名使用。

authc

例: /admins/user/**=authc
,没有参数,表示需要认证(登录)才能使用。

authcBasic

例: /admins/user/**=authcBasic
,没有参数,表示 httpBasic 认证。

user

例: /admins/user/**=user
,没有参数,表示必须存在用户(不一定已通过认证),只要曾被 Shiro 记住过登录状态的用户就可以正常发起请求,比如 rememberMe
)。

logout

例: /logout=logout
,没有参数,注销当前登陆用户,成功后会重定向地址到 /

授权相关

roles

例: /admins/user/**=roles[admin]
,参数可以写多个,用逗号分割,当有多个参数时,例如 admins/user/**=roles[admin, guest]
,每个参数通过才算通过,相当于 hasAllRoles()
方法。

perms

例: /admins/user/**=perms[user:add:*]
,参数可以写多个,用逗号分割,如: /admins/user/**=perms[user:add:*, user:modify:*]
,当有多个参数时必须每个参数都通过才通过,想当于 isPermitedAll()
方法。

port

例: /admins/user/**=port[8081]
,单个参数,当请求的 url 的端口不是 8081
时重定向到 schemal://hostName:8081?queryString
, 也就是说,除了端口,其他东西都会保留。

rest

例: /admins/user/**=rest[user]
,根据请求的方法,相当于 /admins/user/**=perms[user:method]
,其中method为post,get,delete等。

ssl

例: /admins/user/**=ssl
没有参数,表示安全的 url 请求,协议https
,其实也等同于 /admin/user/**=port[443]
,即重定向到 443 端口。

自定义过滤器

roles
过滤器为例: /admin/page1= roles["admin, user"]
,表示 /admin/page1
这个页面必须需要用户同时具备 admin
user
角色才可访问。

我们开发一个自定义的过滤器,判定需要 admin
user
可访问。

package im.zhaojun.filter;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class AnyRolesFilter extends AuthorizationFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        Subject subject = this.getSubject(request, response);
        String[] rolesArray = (String[]) ((String[]) mappedValue);
        if (rolesArray != null && rolesArray.length != 0) {
            for (String role : rolesArray) {
                if (subject.hasRole(role)) {
                    return true;
                }
            }
        } else {
            return true;
        }
        return false;
    }
}

注:这里用到了 ServletRequest
ServletResponse
类,所以还需要导入相应的库:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

然后将其配置IOC 容器中:

<bean id="anyRolesFilter" class="im.zhaojun.filter.AnyRolesFilter"/>

最后为其分配别名,并添加到过滤器链中:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 略 -->
        <property name="filterChainDefinitions">
            <value>
                /login.jsp = anon
                /login = anon
                /user.jsp = anyRoles[user, admin]
                /userList.jsp = perms[select:delete]
                /logout = logout
                /** = authc
            </value>
        </property>
        <property name="filters">
            <map>
                <entry key="anyRoles" value-ref="anyRolesFilter"/>
            </map>
        </property>
    </bean>

我们分别将 /user.jsp
设为 roles[user, admin]
anyRoles[user, admin]

目前 Relam 中的用户 zhao
123456
仅具备 user
角色,所以可以分别测试出, anyRoles
过滤的页面可以正常访问,而 roles
过滤器的内容因未同时具备 user
admin
角色而被拦截,跳转到未授权页面。

通配符

上面的示例中,我们还用到了 **
做通配符,其实还有几个通配符:

?
:匹配一个 字符
,如 /admin?
可以匹配 /admin1
/admin2
,但不能匹配 /admin

*
:匹配零个或一个或多个 字符
,如 /admin*
可以匹配 /admin
/admin1
/admin123
,但不能匹配 /admin/123

**
:匹配零个或多个 路径
,如 /admin/**
可以匹配 /admin
/admin/a/b/c

本章代码地址 : https://github.com/zhaojun1998/Premission-Study/tree/master/Permission-Shiro-07/

原文 

http://www.zhaojun.im/shiro-07/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Shiro 集成 Spring 之过滤器

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址