shiro学习

本文详细介绍了Apache Shiro框架在Java应用中的权限管理实践,包括身份认证、基于角色和权限的访问控制,以及如何利用Shiro内置过滤器进行权限验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一直以来,对于Java开发来说,后台的安全框架,基本就两种,要么用的是shiro来管理,要么就是spring security,自己现在先开始学习shiro,这里就一点一点分享一下自己的学习过程,当然自己现在也是参考网上的相关技术文献,最后还是自己用代码实现一下,这样才能学习认识的更加深刻,废话不说了,过程如下:

1.shiro的身份认证

第一步:收集主体提交的身份和凭证; 

我们使用UsernamePasswordToken,支持最常用的用户名/密码认证方式。这是Shiro的org.apache.shiro.authc.AuthenticationToken接口,这是由Shiro的认证系统代表提交的主体和凭证使用的基本接口的实现。username和password就是和Subject认证主体中对应的身份和凭证做验证的。
第二步:提交该身份和凭证; 

通过SecurityUtils工具类获取当前执行的用户,然后进行身份认证,参考Subject主体,数据库查询出来的信息。
第三步 :如果提交成功,允许访问,否则重新尝试身份验证或阻止访问;

根据认证的结果来处理正确或者错误的结果,所以我们需要将currentUser.login(token)使用try/catch包起来

第四步:退出

与认证相反的是释放所有已知的确定的状态。当主体完成与应用程序交互,可以调用subject.logout()放弃所有的身份信息,subject.logout()会删除所有身份信息以及他们的会话(这里的会话指的是Shiro中的会话)。

2.shiro的权限认证,即授权

权限认证,也就是访问控制,即在应用中控制谁能访问哪些资源。在权限认证中,最核心的三个要素是:权限,角色和用户:
权限(permission)即操作资源的权利,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利;
角色(role):指的是用户担任的的角色,一个角色可以有多个权限;

用户(user): 在Shiro 中,代表访问系统的用户,即上一篇博文提到的Subject认证主体。

2.1 基于角色的访问控制

  也就是说,授权过程是通过判断角色来完成的,哪个角色可以做这件事,哪些角色可以做这件事等等。它有如下API:

方法 作用
hasRole(String roleName) 判断是否有该角色访问权,返回boolen
hasRoles(List<String> roleNames) 判断是否有这些这些角色访问权,返回boolean[]
hasAllRoles(Collection<String> roleNames) 判断是否有这些这些角色访问权,返回boolean

  对这三个API,做一下简单的说明,第一个很简单,传入一个role即可,判断是否拥有该角色访问权,第二个方法是传入一个role的集合,然后Shiro会根据集合中的每一个role做一下判断,并且将每次的判断结果放到boolean[]数组中,顺序与集合中role的顺序一致;第三个方法也是传入一个role的集合,不同的是,返回boolean类型,必须集合中全部role都有才为true,否则为false。

除了这三个API外,Shiro还提供了check的API,与上面不同的是,has-xxx会返回boolean类型的数据,用来判断,而check-xxx不会返回任何东西,如果验证成功就继续处理下面的代码,否则会抛出一个异常,可以用来通过捕获异常来处理。API如下:

方法 作用
checkRole(String roleName) 如果判断失败抛出AuthorizationException异常
checkRoles(String... roleNames) 如果判断失败抛出AuthorizationException异常
checkRoles(Collection<String> roleNames) 如果判断失败抛出AuthorizationException异常

2.2 基于权限的访问控制

  基于权限的访问控制和基于角色的访问控制在原理上是一模一样的,只不过API不同而已,我不再做过多的解释,API如下:

方法 作用
isPermitted(String perm) 判断是否有该权限,返回boolen
isPermitted(List<String> perms) 判断是否有这些这些权限,返回boolean[]
isPermittedAll(Collection<String> perms) 判断是否有这些这些权限,返回boolean
checkPermission(String perm) 如果判断失败抛出AuthorizationException异常
checkPermissions(String... perms) 如果判断失败抛出AuthorizationException异常
checkPermissionsAll(Collection<String> perms) 如果判断失败抛出AuthorizationException异常

3.Shiro的内置过滤器(Default Filters)

Shiro中内置的过滤器有以下几个:

过滤器名 对应的类
anon(匿名) org.apache.shiro.web.filter.authc.AnonymousFilter
authc(身份验证) org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic(http基本验证) org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
logout(退出) org.apache.shiro.web.filter.authc.LogoutFilter
noSessionCreation(不创建session) org.apache.shiro.web.filter.session.NoSessionCreationFilter
perms(许可验证) org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port(端口验证) org.apache.shiro.web.filter.authz.PortFilter
rest(rest方面) org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles(权限验证) org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl(ssl方面) org.apache.shiro.web.filter.authz.SslFilter
user(用户方面) org.apache.shiro.web.filter.authc.UserFilter

  这些内置的过滤器使用方法是这样的,一般先指定一个请求url对应一个过滤器名,由于该过滤器对应一个类,而这个类中会有一个属性,这个属性是当验证失败的时候指定要跳转到那个url的,所以将这个属性配置成验证失败后你要请求的url即可。

我简单说明一下这个配置,比如定义的authc.loginUrl=/login,authc是一个内置过滤器,它对应org.apache.shiro.web.filter.authc.AnonymousFilter类,而这个类中有个loginUrl属性,表示验证失败后将要请求的url映射,这个url映射与一个具体的servlet对应,读到这里,可以和上面的servlet配置对比一下就知道了。roles.unauthorizedUrl也是一样的道理,只不过这里验证失败直接请求一个具体的jsp页面而已。

[users]中是Subject认证主体,就不再赘述了,[urls]中定义需要拦截哪些请求,并做什么验证。比如/login的url映射请求不拦截,因为是登陆的,请求/admin的url映射的话做身份认证,请求/student的url映射的话要做角色认证,且必须是teacher角色才行,请求/teacher的url映射的话需要进行权限认证,必须有user:create权限的用户才可以通过验证。

2.3   url匹配方式

/admin?=authc,表示可以请求以admin开头的字符串,如xxx/adminfefe,但无法匹配多个,即xxx/admindf/admin是不行的 
/admin*=authc表示可以匹配零个或者多个字符,如/admin,/admin1,/admin123,但是不能匹配/admin/abc这种 
/admin/**=authc表示可以匹配零个或者多个路径,如/admin,/admin/ad/adfdf等。 
/admin*/**=authc这个就不多说了,结合上面两个就知道了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值