Shiro【重要概念总结】

一、前言

Shiro【自定义Realm实战】中,已经总结了自定义 Realm 的实现,但在实际开发中,想要使用 Shiro 实现权限控制,除了要知道 Realm 外,本文中总结的其它模块也是不可缺少的。

二、Shiro 中的 Filter

(一)内置 Filter 介绍

Shiro 中提供了 11 个内置的 Filter 供我们使用,分别为:

1)FormAuthenticationFilter

登录拦截器,需要认证登录才能访问。

  1. UserFilter

用户拦截器,表示必须存在用户。

  1. AnonymousFilter

匿名拦截器,不需要登录即可访问的资源,匿名用户或游客,一般用于过滤静态资源。

  1. RolesAuthorizationFilter

角色授权拦截器,验证用户是否拥有指定角色。

参数可写多个,写多个参数时,如: roles["admin,user"],多个参数时必须每个参数都通过才算通过。

如果想要只满足一个角色就通过则需要自定义 Filter。

  1. PermissionsAuthorizationFilter

权限授权拦截器,验证用户是否拥有指定权限。

参数可写多个,写多个参数时,多个参数必须每个参数都通过才算可以。

  1. BasicHttpAuthenticationFilter

httpBasic 身份验证拦截器。

  1. LogoutFilter

退出拦截器,执行后会直接跳转到 shiroFilterFactoryBean.setLoginUrl(); 设置的 url

  1. ortFilter

端口拦截器, 指定端口可通过。

  1. SslFilter

ssl拦截器,只有请求协议是https才能通过。

  1. NoSessionCreationFilter

不创建session(非常用的拦截器)

  1. HttpMethodPermissionFilter

rest 风格拦截器(非常用的拦截器)

(二)Filter配置路径

支持的路径通配符: ?、*、**

?  : 匹配一个字符,如 /user? , 匹配 /user3,但不匹配/user/;
*  : 匹配零个或多个字符串,如 /add* ,匹配 /addtest,但不匹配 /user/1
** : 匹配路径中的零个或多个路径,如 /user/** 将匹 配 /user/xxx 或 /user/xxx/yyy

注:通配符匹配不 会匹配目录分隔符“/”

在shiro中,当有路径匹配上多个过滤器时,会优先命中先定义的过滤器.

例:
/user/**=filter1
/user/add=filter2

那么请求 /user/add 命中的是filter1拦截器

三、Shiro 数据安全之加解密

我们在存储密码这样的非常重要的数据时,都是需要加密的,有时更是需要多重加密。

Shiro 中就内置了很多加密算法供我们使用,我们只需要配置一个 CredentialsMatcher即可。

实例代码如下:

@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();

    //散列算法,使用MD5算法;
    hashedCredentialsMatcher.setHashAlgorithmName("md5");

    //散列的次数,比如散列两次,相当于 md5(md5("xxx"));
    hashedCredentialsMatcher.setHashIterations(2);

    return hashedCredentialsMatcher;
}

四、 Shiro 实现权限控制的方式

我们一共有 3 种实现权限控制的方式:配置文件的方式、注解方式、自己编写代码的方式。

(一)配置文件的方式

这种方式其实就是通过JavaConfig的方式进行必要的配置,在后面的实战项目中有使用,所以此处不做过多介绍。

(二)注解方式

注解要声明在controller层中的方法上,常用的注解如下:

@RequiresRoles(value={"admin", "editor"}, logical= Logical.AND)

需要角色 admin 和 editor两个角色 AND表示两个同时成立

@RequiresPermissions (value={"user:add", "user:del"}, logical= Logical.OR)

需要权限 user:add 或 user:del权限其中一个,OR是或的意思。

@RequiresAuthentication

已经授过权,调用Subject.isAuthenticated()返回true

@RequiresUser

身份验证或者通过记住我登录的

(三)自己编写代码的方式
Subject subject = SecurityUtils.getSubject(); 
//基于角色判断
if(subject.hasRole(“admin”)) {
	//有角色,有权限
} else {
	//无角色,无权限
}
//或者权限判断
if(subject.isPermitted("/user/add")){
    //有权限
}else{
    //无权限
}

五、 Shiro 缓存模块

Shiro 中提供了对认证信息和授权信息的缓存。

注:默认是关闭认证信息缓存的,对于授权信息的缓存 Shiro 默认开启的(因为授权的数据量大)

在分析了认证和授权的源码之后我们就会发现 AuthenticatingRealm 及 AuthorizingRealm 分别提供了对 AuthenticationInfo 和 AuthorizationInfo 信息的缓存。

在实际开发中,我们还可以通过整合 Redis 等缓存中间件来提升系统性能。

六、Shiro Session 模块

关于 Shiro 中的 Session 模块,有以下几个概念需要了解:

Session: 会话

用户和程序直接的链接,程序可以根据session识别到哪个用户,和javaweb中的session类似。

SessionManager:会话管理器

会话管理器管理所有subject的所有操作,是shiro的核心组件。

核心方法:

//开启一个session
Session start(SessionContext context);
//指定Key获取session
Session getSession(SessionKey key)

注:Shiro 中的 SessionManager 有多个实现。

SessionDao :会话存储

是用于session持久化的,SessionManager只是负责session的管理,持久化的工作是由SessionDAO完成的。

在实际开发中,我们还可以通过整合 Redis 等缓存中间件来解决分布式下的 Session 问题。

核心方法:

//创建
Serializable create(Session session);
//获取
Session readSession(Serializable sessionId) throws UnknownSessionException;
//更新
void update(Session session) 
//删除,会话过期时会调用
void delete(Session session);
//获取活跃的session
Collection<Session> getActiveSessions();

注:Shiro 中的 SessionDao 有多个实现,如:

SessionDAO
AbstractSessionDAO
 	CachingSessionDAO
 		EnterpriseCacheSessionDAO
 	MemorySessionDAO

Java新手,若有错误,欢迎指正!

posted @ 2021-03-04 15:49  跑调大叔!  阅读(165)  评论(0编辑  收藏  举报