Shiro(4)默认鉴权与自定义鉴权
来源:互联网 发布:矩阵行列式计算公式 编辑:程序博客网 时间:2024/05/05 08:20
=========默认鉴权========
过滤链中定义:
<!-- 过滤链定义 --><property name="filterChainDefinitions"><value>.../pages/User/create.do* = perms[User:create]...</value></property>
这段配置的含义是:/pages/User/create.do*这样的请求路径,需要鉴权,且需要用户有“User:create”的权限字符串。
perms是拦截器的名字,默认实现类是:org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
这个过滤器会得到配置中请求路径对应的权限字符串,如“User:create”,然后到realm中查找当前用户包含的权限,具体来说是调用reaml的回调函数:
/** * 鉴权回调函数,提取当事人的角色和权限 * principals 当事人 */ protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { //用户名 String username = (String) principals.fromRealm( getName()).iterator().next(); /*这些代码应该是动态从数据库中取出的,此处写死*/ if(username!=null&&username.equals("admin")){ SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();// info.addRole("admin");//添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色 info.addStringPermission("User:create"); info.addStringPermission("/pages/index.jsp");//添加权限 info.addStringPermission("/pages/info.jsp");//添加权限 return info; } return null; }
此代码属于自定义Realm——public class CustomRealm extends AuthorizingRealm
代码中我们使用的是测试数据,直接往info里面添加角色字符串和权限字符串,我们也可以从数据库中获取,这不是本节重点。
现在关键要明白SecurityManager是从请求端得到应该有的权限字串,从Realm得到当事人具备的角色和权限字串,然后比对,比对成功说明鉴权成功,否则鉴权失败。
事实上,这种配置鉴权的方式,连自定义Realm都不需要,用户信息、角色信息、权限信息都可以配置:
[users]# user1 = sha256-hashed-hex-encoded password, role1, role2, ...user1 = 2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b, role1, role2, ... [roles]# 'admin' role has all permissions, indicated by the wildcard '*'admin = *# The 'schwartz' role can do anything (*) with any lightsaber:schwartz = lightsaber:*# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with# license plate 'eagle5' (instance specific id)goodguy = winnebago:drive:eagle5
这点可以参考官方文档。
===================自定义鉴权=================
往往我们的项目,特别是遗留项目都会设计几张表来存储用户信息和角色信息以及权限映射信息,所以Realm这块,一般要自定义。
而且通常的作法是直接用请求的URL作为权限字符串的,也就是不需要URL再去映射一些权限字符串,所以过滤器这块,我们可能也需要自定义。
自定义鉴权过滤器:
package javacommon.shiro;import java.io.IOException;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;/** * 基于URL的权限判断过滤器<p> * 我们自动根据URL产生所谓的权限字符串,这一项在Shiro示例中是写在配置文件里面的,默认认为权限不可动态配置<p> * URL举例:/User/create.do?***=*** -->权限字符串:/User/create.do * @author zhengwei lastmodified 2013年8月15日 * */public class URLPermissionsFilter extends PermissionsAuthorizationFilter{/** *@param mappedValue 指的是在声明url时指定的权限字符串,如/User/create.do=perms[User:create].我们要动态产生这个权限字符串,所以这个配置对我们没用 */public boolean isAccessAllowed(ServletRequest request,ServletResponse response, Object mappedValue) throws IOException { return super.isAccessAllowed(request, response, buildPermissions(request));}/** * 根据请求URL产生权限字符串,这里只产生,而比对的事交给Realm * @param request * @return */protected String[] buildPermissions(ServletRequest request) {String[] perms = new String[1];HttpServletRequest req = (HttpServletRequest) request;String path = req.getServletPath();perms[0] = path;//path直接作为权限字符串/*String regex = "/(.*?)/(.*?)\\.(.*)";if(url.matches(regex)){Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(url);String controller = matcher.group(1);String action = matcher.group(2);}*/return perms;}}
可以看出我们直接将请求路径作为权限字符串,过滤器会去调用Realm,所以自定义Realm中也要为用户添加同样格式的权限字符串
info.addStringPermission("/pages/index.jsp");//添加权限,admin可访问这个路径
最后再来看看全局Filter的配置:
<!-- Shiro Filter 拦截器相关配置 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">...<property name="filters"><util:map><entry key="authc" value-ref="myAuthenFilter" /><entry key="perms" value-ref="URLPermissionsFilter" /></util:map></property><!-- 过滤链定义 --><property name="filterChainDefinitions"><value>/login.jsp = authc/pages/* = authc,perms/logout.do = logout...</value></property></bean>...<!-- 自定义鉴权拦截器 --><bean id="URLPermissionsFilter" class="javacommon.shiro.URLPermissionsFilter" />
这段配置意味着访问/pages/*都需要鉴权,而鉴权使用的是自定义的拦截器。
测试:
以admin身份登录并访问pages/info.jsp,没问题,因为它拥有这个权限。
访问pages/NB.jsp,因为这个路径没有添加到admin的权限中,所以鉴权失败,将跳转到unauthorizedUrl指定的路径。
小节:
对于客户要求程序开发者自己管理权限,而且不需要动态配置的情况,使用默认配置法,非常简单。
当需要动态管理权限,那就要自定义Realm和Filter,关键在于请求URL--》权限字符串,Realm可返回一个用户拥有的权限字符串。
这些字符串应该能比对上。
- Shiro(4)默认鉴权与自定义鉴权
- shiro笔记4《shiro默认拦截器》
- Shiro笔记(二)----shiro源码与默认提供的示例
- shiro教程(4)-shiro与项目集成开发
- 自定义(补充)shiro标签
- (六)shiro自定义realm
- springboot集成Shiro,添加自定义filter后shiro的默认filter无法使用
- apache shiro自定义shiro
- 自定义shiro
- shiro默认拦截器
- shiro默认拦截器
- shiro默认拦截器
- shiro默认拦截器
- shiro默认filter
- shiro源码分析篇4:自定义缓存
- Shiro 自定义realm授权与认证的实现
- shiro表单认证(系统默认的form认证器)
- Shiro学习--与SpringMVC整合(数据库,Shiro注解和Shiro标签)
- 【PHP小错误整理】在类面调用自定义方法需要注意的问题
- Android 中自定义控件和属性(attr.xml,declare-styleable,TypedArray)的方法和使用
- hdu 4667(几何)
- 在连接点中设置传入参数时出错,怎么办?【ATL事件】
- GDALOpen 代码分析
- Shiro(4)默认鉴权与自定义鉴权
- 黑马程序员_7K月薪面试题之_交通灯管理系统
- 读串口总结
- 手机导航程序搜索不到GPS信号怎么办?
- 以自动化测试撬动遗留系统
- 手把手教你在Windows端搭建Redmine项目管理软件
- 移动应用中的流设计
- php案例01—在页面中打印服务器的时间
- VC用ADO访问数据库全攻略