shiro(3)-shiro核心

简介:

身份认证

身份认证分三个步骤

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 {
 //don't 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 {
 //don't 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 {
 //don't 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 {
 //don't 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 - they're 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链
目录
相关文章
|
存储 JSON 前端开发
Shiro实现记住我(十)
Shiro实现记住我(十)
429 0
Shiro实现记住我(十)
|
存储 缓存 安全
02 Shiro的架构
02 Shiro的架构
56 0
|
安全 Java 测试技术
深入理解Shiro(上)
深入理解Shiro(上)
88 0
|
安全 Java 容器
深入理解Shiro(下)
深入理解Shiro(下)
81 0
|
存储 缓存 安全
Shiro学习之Shiro简介
Shiro学习之Shiro简介
109 0
|
消息中间件 安全 JavaScript
再见了 shiro !
再见了 shiro !
|
存储 缓存 安全
Shiro框架01之什么是shiro+shiro的架构+权限认证
Shiro框架01之什么是shiro+shiro的架构+权限认证
Shiro框架01之什么是shiro+shiro的架构+权限认证
|
SQL 安全 Java
Shiro - 基础篇(下)
Shiro - 基础篇(下)
121 0
Shiro - 基础篇(下)
|
缓存 Java 数据库
Shiro - 基础篇(上)
Shiro - 基础篇(上)
156 0
Shiro - 基础篇(上)
|
缓存 安全 Java
Shiro(一):shiro简介
Shiro(一):shiro简介
213 0
Shiro(一):shiro简介