shiro(3)-shiro核心
身份认证
![](http://pic002.cnblogs.com/images/2011/133059/2011091211114554.png)
身份认证分三个步骤
1)提交主题和凭据
2)进行身份认证
3)判断是通过,重新提交还是不通过
验证顺序
![](http://pic002.cnblogs.com/images/2011/133059/2011091211184366.png)
1)调用subject的login方法,提交主体和凭据。
2)得到对应操作的Security Manager
3)通过Sceurity Manager得到对应的Autherticator实例
4)根据配置策略查找对应的桥信息
5)通过桥信息到对应的配置处理进行身份验证
验证器
如果你想配置一个自定义的验证器
可以在配置文件中使用
[main] authenticator = com.foo.bar.CustomAuthenticator securityManager.authenticator = $authenticator
配置策略信息
AtLeastOneSuccessfulStrategy 如果一个验证成功,则验证结果为成功
FirstSuccessfulStrategy 只有第一个成功,才算成功
AllSuccessfulStrategy 所有的都必须成功
对应的在配置文件中的策略使用如下
shiro.ini [main] authcStrategy = org.apache.shiro.authc.pam.FirstSuccessfulStrategy securityManager.authenticator.authenticationStrategy = $authcStrategy ...
执行顺序
1)隐式顺序
blahRealm = com.company.blah.Realm fooRealm = com.company.foo.Realm barRealm = com.company.another.Realm
按上下顺序执行
2)指定顺序
blahRealm = com.company.blah.Realm fooRealm = com.company.foo.Realm barRealm = com.company.another.Realm securityManager.realms = $fooRealm, $barRealm, $blahRealm ...
按指定的顺序执行
授权
![](http://pic002.cnblogs.com/images/2011/133059/2011091211351153.png)
控制谁有权限访问应用程序
授权的几个要素:权限,角色和用户。
三种权限的判断方式
1)编程
角色判断
Subject currentUser = SecurityUtils.getSubject(); if (currentUser.hasRole("administrator")) { //show the admin button } else { //dont show the button? Grey it out? }
hasRole(String roleName) 主题是否已分配给指定的角色
hasRoles(List String roleNames) 是否包含指定的角色
hasAllRoles(Collection String roleNames) 是否包含指定的所有角色
角色断言
Subject currentUser = SecurityUtils.getSubject(); //guarantee that the current user is a bank teller and //therefore allowed to open the account: currentUser.checkRole("bankTeller"); openBankAccount();
checkRole(String roleName) 断言是否是指定角色
checkRoles(Collection String roleNames) 断言是否包含以下角色
checkRoles(String... roleNames) 断言是否包含所有角色
如果判断指定用户是否有权限访问指定名称的打印机
那么就会用到下列几个方法
Permission printPermission = new PrinterPermission("laserjet4400n", "print"); Subject currentUser = SecurityUtils.getSubject(); if (currentUser.isPermitted(printPermission)) { //show the Print button } else { //dont show the button? Grey it out? }
isPermitted(Permission p) 判断主题是否允许执行一个动作
isPermitted(List Permission perms) 是否允许执行一组动作
isPermittedAll(Collection Permission perms) 是否允许执行所有动作
基于字符串的权限检查
Subject currentUser = SecurityUtils.getSubject(); if (currentUser.isPermitted("printer:print:laserjet4400n")) { //show the Print button } else { //dont show the button? Grey it out? }也可以如下使用
Subject currentUser = SecurityUtils.getSubject(); Permission p = new WildcardPermission("printer:print:laserjet4400n"); if (currentUser.isPermitted(p) { //show the Print button } else { //dont show the button? Grey it out? }
权限断言类似于角色断言。
2)annocation方式
The RequiresAuthentication annotation@RequiresAuthentication public void updateAccount(Account userAccount) { //this method will only be invoked by a //Subject that is guaranteed authenticated }
等同于下述代码
public void updateAccount(Account userAccount) { if (!SecurityUtils.getSubject().isAuthenticated()) { throw new AuthorizationException(...); //Subject is guaranteed authenticated here }
The RequiresGuest annotation
@RequiresGuest public void signUp(User newUser) { //this method will only be invoked by a //Subject that is unknown/anonymous }
等同于
public void signUp(User newUser) { Subject currentUser = SecurityUtils.getSubject(); PrincipalCollection principals = currentUser.getPrincipals(); if (principals != null !principals.isEmpty()) { //known identity - not a guest: throw new AuthorizationException(...); //Subject is guaranteed to be a guest here }
The RequiresPermissions annotation
@RequiresPermissions("account:create") public void createAccount(Account account) { //this method will only be invoked by a Subject //that is permitted to create an account }
等同于
public void createAccount(Account account) { Subject currentUser = SecurityUtils.getSubject(); if (!subject.isPermitted("account:create")) { throw new AuthorizationException(...); //Subject is guaranteed to be permitted here }
The RequiresRoles permission
@RequiresRoles("administrator") public void deleteUser(User user) { //this method will only be invoked by an administrator }
等同于
public void deleteUser(User user) { Subject currentUser = SecurityUtils.getSubject(); if (!subject.hasRole("administrator")) { throw new AuthorizationException(...); //Subject is guaranteed to be an administrator here }
The RequiresUser annotation
@RequiresUser public void updateAccount(Account account) { //this method will only be invoked by a user //i.e. a Subject with a known identity }
等同于
public void updateAccount(Account account) { Subject currentUser = SecurityUtils.getSubject(); PrincipalCollection principals = currentUser.getPrincipals(); if (principals == null || principals.isEmpty()) { //no identity - theyre anonymous, not allowed: throw new AuthorizationException(...); //Subject is guaranteed to have a known identity here }
授权顺序
![](http://pic002.cnblogs.com/images/2011/133059/2011091212023555.png)
1)应用程序调用主题,判断hasRole,isPermitted得到角色或者用户权限的列表。
2)组成对应的授权方法
3)协调如何授权
4)通过桥进行各种方式的授权
web应用
配置web.xml
listener listener-class org.apache.shiro.web.env.EnvironmentLoaderListener /listener-class /listener filter filter-name ShiroFilter /filter-name filter-class org.apache.shiro.web.servlet.ShiroFilter /filter-class /filter filter-mapping filter-name ShiroFilter /filter-name url-pattern /* /url-pattern /filter-mapping如果你愿意你可以自定义一个web应用
context-param param-name shiroEnvironmentClass /param-name param-value com.foo.bar.shiro.MyWebEnvironment /param-value /context-param如果你想改变shiro.ini的位置,那么你可以指定
context-param param-name shiroConfigLocations /param-name param-value YOUR_RESOURCE_LOCATION_HERE /param-value /context-param
shiro.ini中的[urls]配置
例如:
... [urls] /index.html = anon /user/create = anon /user/** = authc /admin/** = authc, roles[administrator] /rest/** = authc, rest /remoting/rpc/** = authc, perms["remote:invoke"]假如你有如下设置
/account/** = ssl, authc/account下的任何应用程序都将触动ssl和authc链
Shiro 使用详解(下) 相比有做过企业级开发的童鞋应该都有做过权限安全之类的功能吧,最先开始我采用的是建用户表,角色表,权限表,之后在拦截器中对每一个请求进行拦截,再到数据库中进行查询看当前用户是否有该权限,这样的设计能满足大多数中小型系统的需求。不过这篇所介绍的Shiro能满足之前的所有需求,并且使用简单,安全性高,而且现在越来越的多企业都在使用Shiro,这应该是一个收入的你的技能库。
相关文章
- 一步步实现React-Hooks核心原理
- 【Netty】Netty 核心组件 ( ChannelOption | EventLoopGroup )
- 九大核心专题,630页内容,熬夜23天吃透,我收割了3个大厂offer
- Spring框架核心解析详解程序员
- 核心探索Linux中CPU核心数量(linux查看几个cpu)
- 最小核心:Linux的微型版本(最小的linux内核)
- 对 Python 开发者而言,IPython 仍然是 Jupyter Notebook 的核心
- Shiro踢出Redis,安全注定无悔(shiro踢出redis)
- 改善性能Shiro用Redis做缓存(shiro使用redis)
- 存储使用Redis存储保障Shiro安全性(shiro用redis)
- Shiro使用Redis进行托管(shiro托管redis)
- MySQL数据库服务器端核心参数详解和推荐配置
- android开发教程之时间对话框核心代码