zl程序教程

您现在的位置是:首页 >  其它

当前栏目

shiro(3)-shiro核心

核心 shiro
2023-09-14 08:58:21 时间

身份认证

身份认证分三个步骤

1)提交主题和凭据

2)进行身份认证

3)判断是通过,重新提交还是不通过

验证顺序

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

...

按指定的顺序执行

授权

控制谁有权限访问应用程序

授权的几个要素:权限,角色和用户。

三种权限的判断方式

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

}

授权顺序

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,这应该是一个收入的你的技能库。