Shiro笔记五:Shiro内置Filter过滤器
shiro内置的过滤器
- 核心过滤器类:DefaultFilter,配置哪个路径对应哪个拦截器进行处理。
- authc:org.apache.shiro.web.filter.authc.FormAuthenticationFilter
需要认证登录才能访问
- user:org.apache.shiro.web.filter.authc.UserFilter
用户拦截器,表示必须存在用户。
- anon:org.apache.shiro.web.filter.authc.AnonymousFilter
匿名拦截器,不需要登录即可访问的资源,匿名用户或游客,一般用于过滤静态资源。
- roles:org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
角色授权拦截器,验证用户是或否拥有角色。
参数可写多个,表示某些角色才能通过,多个参数时写 roles[“admin,user”],当有多个参数时必须每个
参数都通过才算通过
- perms:org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
1、权限授权拦截器,验证用户是否拥有权限
2、参数可写多个,表示需要某些权限才能通过,多个参数时写 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配置
- Filter配置原则
1、路径通配符支持 ?、*、**,注意通配符匹配不 包括目录分隔符“/”
2、* 可以匹配所有,不加*可以进行前缀匹配,但多个冒号就需要多个 * 来匹配
- 通配符
URL权限采取第一次匹配优先的方式
? : 匹配一个字符,如 /user? , 匹配 /user3,但不匹配/user/;
* : 匹配零个或多个字符串,如 /add* ,匹配 /addtest,但不匹配 /user/1
** : 匹配路径中的零个或多个路径,如 /user/** 将匹 配 /user/xxx 或 /user/xxx/yyy
例子:
/user/**=filter1
/user/add=filter2
请求 /user/add 命中的是filter1拦截器
- 通配符性能
通配符比字符串匹配会复杂点,所以性能也会稍弱,推荐是使用字符串匹配方式
shiro数据安全之数据加解密
- 加解密
明文数据容易泄露,比如密码明文存储,万一泄露则会造成严重后果
- 散列算法
一般叫hash,简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数,适合存储
密码,比如MD5
- 加盐salt
如果直接通过散列函数得到加密数据,容易被对应解密网站暴力破解,一般会在应用程序里面加特殊的
自动进行处理,比如用户id,例子:加密数据 = MD5(明文密码+用户id), 破解难度会更大,也可以使用
多重散列,比如多次md5
- Shiro的安全处理
Shiro里面 CredentialsMatcher,用来验证密码是否正确
源码:AuthenticatingRealm -> assertCredentialsMatch()
- 一般会自定义规则
public void abc() {
@Bean public HashedCredentialsMatcher hashedCredentialsMatcher () {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//散列算法,使用MD5算法;
hashedCredentialsMatcher.setHashAlgorithmName("md5");
//散列的次数,比如散列两次,相当于 md5(md5("xxx"));
hashedCredentialsMatcher.setHashIterations(2);
return hashedCredentialsMatcher; }
}
}
shiro权限控制之注解和编程方式还可以使用配置文件方式
- 注解方式
@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{
//无权限
}
- 常见API
subject.hasRole(“xxx”);
subject.isPermitted(“xxx”);
subject. isPermittedAll(“xxxxx”,“yyyy”);
subject.checkRole(“xxx”); // 无返回值,可以认为内部使用断言的方式
Shiro缓存模块
- shiro缓存
shiro中提供了对认证信息和授权信息的缓存。
默认是关闭认证信息缓存的,对于授权信息的缓存shiro默认开启的(因为授权的数据量大)
AuthenticatingRealm 及 AuthorizingRealm 分别提供了对AuthenticationInfo 和 AuthorizationInfo 信息的缓存。
- Shiro的缓存模块Cache Manager
Shiro的Session模块和SessionManager
- Session
用户和程序直接的链接,程序可以根据session识别到哪个用户,和javaweb中的session类似
- 会话管理器SessionManager
1、会话管理器管理所有subject的所有操作,是shiro的核心组件
2、核心方法:
//开启一个sessionSession start(SessionContext context);
//指定Key获取session
Session getSession(SessionKey key)
- SessionDao会话存储持久化
SessionDAO AbstractSessionDAO CachingSessionDAO EnterpriseCacheSessionDAO
MemorySessionDAO核心方法:
//创建
Serializable create(Session session);
//获取
Session readSession(Serializable sessionId) throws UnknownSessionException;
//更新
void update(Session session)
//删除,会话过期时会调用
void delete(Session session);
//获取活跃的session
Collection 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拦截器处理即可