Shiro内置的Filter过滤器
核心过滤器类:DefaultFilter, 配置哪个路径对应哪个拦截器进行处理
- anon:org.apache.shiro.web.filter.authc.AnonymousFilter
匿名拦截器,不需要登录即可访问的资源,匿名用户或游客,一般用于过滤静态资源。
- authc:org.apache.shiro.web.filter.authc.FormAuthenticationFilter
需要认证登录才能访问
- user:org.apache.shiro.web.filter.authc.UserFilter
用户拦截器,表示必须存在用户。
- org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
角色授权拦截器,验证用户是或否拥有角色。
参数可写多个,表示某些角色才能通过,多个参数时写 roles["admin,user"],当有多个参数时必须每个参数都通过才算通过
源码如下:
- perms:org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
权限授权拦截器,验证用户是否拥有权限
参数可写多个,表示需要某些权限才能通过,多个参数时写 perms["user, admin"],当有多个参数时必须每个参数都通过才算可以
源码可可自己查看下
- authcBasic:org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
httpBasic 身份验证拦截器。
- logout:org.apache.shiro.web.filter.authc.LogoutFilter
退出拦截器,执行后会直接跳转到shiroFilterFactoryBean.setLoginUrl();
设置的 url
- port:org.apache.shiro.web.filter.authz.PortFilter
端口拦截器, 可通过的端口。
- ssl:org.apache.shiro.web.filter.authz.SslFilter
ssl拦截器,只有请求协议是https才能通过。
Shiro的Filter配置路径
- 路径通配符支持 ?、*、**,注意通配符匹配不包括目录分隔符“/”
- * 可以匹配所有,不加*可以进行前缀匹配,但多个冒号就需要多个 * 来匹配
URL权限采取第一次匹配优先的方式 ? : 匹配一个字符,如 /user? , 匹配 /user3,但不匹配/user/; * : 匹配零个或多个字符串,如 /add* ,匹配 /addtest,但不匹配 /user/1 ** : 匹配路径中的零个或多个路径,如 /user/** 将匹 配 /user/xxx 或 /user/xxx/yyy 例子 /user/**=filter1 /user/add=filter2 请求 /user/add 命中的是filter1拦截器
- 性能问题:通配符比字符串匹配会复杂点,所以性能也会稍弱,推荐是使用字符串匹配方式
Shiro 数据安全之数据加解密
- 为啥要加解密
明文数据容易泄露,比如密码明文存储,万一泄露则会造成严重后果
- 什么是散列算法
一般叫hash算法,简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数,适合存储密码。
- 什么是salt(盐)
如果直接通过散列函数得到加密数据,容易被对应解密网站暴力破解,一般会在应用程序里面加特殊的自动进行处理,比如用户id,例子:加密数据 = MD5(明文密码+用户id), 破解难度会更大,也可以使用多重散列,比如多次md5
- Shiro里面 CredentialsMatcher,用来验证密码是否正确
源码:
AuthenticatingRealm -> assertCredentialsMatch()
自定义验证规则
Shiro权限控制方式
配置文件的方式
使用ShiroConfig,后续会涉及到。
注解方式
- @RequiresRoles(value={"admin", "editor"}, logical= Logical.AND)
需要角色 admin 和 editor两个角色 AND表示两个同时成立
-
@RequiresPermissions (value={"user:add", "user:del"}, logical= Logical.OR)
需要权限 user:add 或 user:del权限其中一个,OR是或的意思。
编程方式
-
常见API
subject.hasRole("xxx");
subject.isPermitted("xxx");
subject. isPermittedAll("xxxxx","yyyy");
subject.checkRole("xxx"); // 无返回值,可以认为内部使用断言的方式
Shiro 缓存模块讲解
- 什么是shiro缓存
shiro中提供了对认证信息和授权信息的缓存。
默认是关闭认证信息缓存的,对于授权信息的缓存shiro默认开启的(因为授权的数据量大)。
- AuthenticatingRealm 及 AuthorizingRealm 分别提供了对AuthenticationInfo 和 AuthorizationInfo 信息的缓存。
Shiro Session模块
- 什么是会话session
用户和程序直接的链接,程序可以根据session识别到哪个用户,和javaweb中的session类似
- 什么是会话管理器SessionManager
会话管理器管理所有subject的所有操作,是shiro的核心组件
-
核心方法:
- shiro中的会话管理器有多个实现
- SessionDao 会话存储/持久化,继承关系
- 核心方法
//创建 Serializable create(Session session); //获取 Session readSession(Serializable sessionId) throws UnknownSessionException; //更新 void update(Session session) //删除,会话过期时会调用 void delete(Session session); //获取活跃的session Collection<Session> getActiveSessions();
- 附属资料:
RememberMe 1、 Cookie 写到客户端并 保存 2、 通过调用subject.login()前,设置 token.setRememberMe(true); 3、 关闭浏览器再重新打开;会发现浏览器还是记住你的 4、 注意点: - subject.isAuthenticated() 表示用户进行了身份验证登录的,即Subject.login 进行了登录 - subject.isRemembered() 表示用户是通过RememberMe登录的 - subject.isAuthenticated()==true,则 subject.isRemembered()==false, 两个互斥 - 总结:特殊页面或者API调用才需要authc进行验证拦截,该拦截器会判断用户是否是通过 subject.login()登录,安全性更高,其他非核心接口或者页面则通过user拦截器处理即可