shiro(2)-架构与配置

认证就是用户确认身份的过程,确认登录的用户身份能够操作的内容。

使用shiro认证分为以下几个步骤:

1,得到主体的认证和凭据。

// let's login the current user so we can check against roles and permissions:
        if (!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);

2,提交认证和凭据给身份验证系统。

Subject currentUser = SecurityUtils.getSubject();
currentUser.login(token);

3,判断是否允许访问,重试认证或者阻止访问。

try {
                currentUser.login(token);
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
            }

其中Remember Me的功能包括两个方法,一个是

isRemembered

boolean isRemembered()

非匿名登录的用户可以记住上次使用的主题的信息。

isAuthenticated

boolean isAuthenticated()

在此期间需要使用有效的凭据登录系统,否则值为false.

授权操作

授权的例子就是是否可以访问某个页面,可以操作某个按钮,是否可以编缉对应的数据等。

如何在shiro中使用授权

1,使用编程方式

判断是否有管理员角色

if (currentUser.hasRole("admin")) {

判断用户是否有打印的权限

Permission printPermission = new PrinterPermission(“laserjet3000n”,“print”);
If (currentUser.isPermitted(printPermission)) {
    //do one thing (show the print button?)‏
} else {
    //don’t show the button?
}

也可以使用字符串的方式验证

String perm = “printer:print:laserjet4400n”;

if(currentUser.isPermitted(perm)){
    //show the print button?
} else {
    //don’t show the button?
}

2,使用注释方式

 判断用户是否有 创建账户权限

//Will throw an AuthorizationException if none
//of the caller’s roles imply the Account 
//'create' permission\u000B
@RequiresPermissions(“account:create”)‏
public void openAccount( Account acct ) { 
    //create the account
}

判断用户角色,如果符合角色,可以使用对应方法

//Throws an AuthorizationException if the caller
//doesn’t have the ‘teller’ role:

@RequiresRoles( “teller” )
public void openAccount( Account acct ) { 
    //do something in here that only a teller
    //should do
}

3,使用jsp taglib

 判断用户是否有管理权限

<%@ taglib prefix=“shiro” uri=http://shiro.apache.org/tags %>
<html>
<body>
    <shiro:hasPermission name=“users:manage”>
        <a href=“manageUsers.jsp”>
            Click here to manage users
        </a>
    </shiro:hasPermission>
    <shiro:lacksPermission name=“users:manage”>
        No user management for you!
    </shiro:lacksPermission>
</body>
</html>

从高的级别来看shiro:

看一下官方的图

应用程序调用subject(主题),主题可以是一个用户也可以是与系统交互的另一个系统,主题绑定shiro的权限管理,SecurityManager(安全管理),它控制与有与主题相关的安全操作。Realm(桥梁)它是安全与数据之间的桥,它封装了比如DAO的配置信息,可以指定连接的数据源,也可使用其它的认证方式,如LDAP等。

然后看一下详细的架构图:

Subject (org.apache.shiro.subject.Subject)

主题:与系统交互的第三方如(用户,cron服务,第三方应用)等。

SecurityManager (org.apache.shiro.mgt.SecurityManager)

shiro系统的核心,协调主题使用的操作,验证,配置等。

Authenticator (org.apache.shiro.authc.Authenticator)

身份验证组件,对企图登录系统的用户进行身份的验证。其中包含一个Authentication Strategy

 (org.apache.shiro.authc.pam.AuthenticationStrategy)组件。配置验证成功与失败的条件。

Authorizer (org.apache.shiro.authz.Authorizer)

授权组件,指用户访问特定应用程序的机制。

SessionManager (org.apache.shiro.session.mgt.SessionManager)

管理会话如何创建生命周期。其中包括的sessiondao是管理会议数据的持久操作:SessionDAO (org.apache.shiro.session.mgt.eis.SessionDAO),代表执行sessionManager的CRUD操作。

CacheManager (org.apache.shiro.cache.CacheManager)

缓存管理模块。

Cryptography (org.apache.shiro.crypto.*)

加密模块。

Realms (org.apache.shiro.realm.Realm)

多种方式处理的桥梁。

多种配置方式:

与spring,jboss,guice等进行配置。

1,编程方式配置

例如:

Realm realm = //instantiate or acquire a Realm instance.  We'll discuss Realms later.

SecurityManager securityManager = new DefaultSecurityManager(realm);
//Make the SecurityManager instance available to the entire application via static memory:
SecurityUtils.setSecurityManager(securityManager);

2,sessionManager对象图

如果你想使用sessionManager配置自定义的sessionDao信息,进行自定义会话管理

...

DefaultSecurityManager securityManager = new DefaultSecurityManager(realm);
SessionDAO sessionDAO = new CustomSessionDAO();

((DefaultSessionManager)securityManager.getSessionManager()).setSessionDAO(sessionDAO);
...

3,INI配置

1) 创建一个INI从SecurityManager

可以从多种方式读取INI配置文件的信息,如文件系统,类路径等

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.util.Factory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.config.IniSecurityManagerFactory;
...

Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);

2) 通过Ini实例读取

类似于Properties的方式

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.util.Factory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.config.Ini;
import org.apache.shiro.config.IniSecurityManagerFactory;
...

Ini ini = new Ini();
//populate the Ini instance as necessary
...
Factory<SecurityManager> factory = new IniSecurityManagerFactory(ini);
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);

加载之后就可以操作INI的配置了。

4,INI配置

每一个节点都是单独的,不可以重复,注释可以使用#或者;

配置示例

# =======================
# Shiro INI configuration
# =======================
[main]
# Objects and their properties are defined here, 
# Such as the securityManager, Realms and anything
# else needed to build the SecurityManager

[users]
# The 'users' section is for simple deployments
# when you only need a small number of statically-defined 
# set of User accounts.

[roles]
# The 'roles' section is for simple deployments
# when you only need a small number of statically-defined
# roles.

[urls]
# The 'urls' section is used for url-based security
# in web applications.  We'll discuss this section in the
# Web documentation

1) [main]

配置sessionManager的实例和它的依赖。

配置示例

[main]
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher

myRealm = com.company.security.shiro.DatabaseRealm
myRealm.connectionTimeout = 30000
myRealm.username = jsmith
myRealm.password = secret
myRealm.credentialsMatcher = $sha256Matcher
securityManager.sessionManager.globalSessionTimeout = 1800000

定义一个对象

[main]
myRealm = com.company.shiro.realm.MyRealm
...

简单的属性设置

...
myRealm.connectionTimeout = 30000
myRealm.username = jsmith
...

配置信息将转入到对应的set方法中

...
myRealm.setConnectionTimeout(30000);
myRealm.setUsername("jsmith");
...

参考值

你可以使用$符号引用先前定义的一个对象的实例

...
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
...
myRealm.credentialsMatcher = $sha256Matcher
...

嵌套属性

...
securityManager.sessionManager.globalSessionTimeout = 1800000
...

将被注入到下面的程序中

securityManager.getSessionManager().setGlobalSessionTimeout(1800000);

引用其它的属性

sessionListener1 = com.company.my.SessionListenerImplementation
...
sessionListener2 = com.company.my.other.SessionListenerImplementation
...
securityManager.sessionManager.sessionListeners = $sessionListener1, $sessionListener2

以键值的配置方式

object1 = com.company.some.Class
object2 = com.company.another.Class
...
anObject = some.class.with.a.Map.property

anObject.mapProperty = key1:$object1, key2:$object2

2) [users]

在用户比较少的情况下这种配置信息是有效的

[users]
admin = secret
lonestarr = vespa, goodguy, schwartz
darkhelmet = ludicrousspeed, badguy, schwartz

3) [roles]

如果角色信息比较少的情况下可以使用这项配置

[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

4) [urls]

配置url等可访问的资源信息。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏吴伟祥

- 的iPhone 原

tutor ['tjuːtə]n. 导师;家庭教师;助教 vt. 辅导;约束         tutorial  [tjuː'tɔːrɪəl]  adj. 辅...

10330
来自专栏JavaEE

spring整合shiro(含MD5加密)shiro简介:开发环境及技术:一、数据库设计:二、项目环境搭建:三、项目功能实现四、项目测试五、知识点补充总结:

816130
来自专栏开发技术

spring-boot-2.0.3不一样系列之shiro - 搭建篇

       上一篇:spring-boot-2.0.3不一样系列之国际化,讲了如何实现国际化,实际上我工作用的模版引擎是freemaker,而不是thymel...

1.4K10
来自专栏JavaEE

springboot快速入门前言:一、springboot简介:二、springboot常用知识点:总结:

正所谓,天下武功,唯快不破,在当今生活节奏越来越快的时代,我们也要讲求效率,也要追求一个快字(不过有些方面还是不能快的,不要当快男哦)。springboot就是...

11510
来自专栏pangguoming

Spring Boot 集成Shiro和CAS

Spring Boot 集成Shiro和CAS 请大家在看本文之前,先了解如下知识点:  1、Shiro 是什么?怎么用?  2、Cas 是什么?怎么用?  3...

3.4K50
来自专栏黄日成的专栏

浅析 P2P 穿越 NAT 的原理、技术、方法 (上)

在 NAT 环境下,实现 P2P 通信的完整解决方案包括几个部分呢?相关的原理、方法、技术有哪些?

2.5K10
来自专栏拂晓风起

nodejs搭配phantomjs highcharts后台生成图表

20430
来自专栏张戈的专栏

分享一次Linux任务计划crontab不执行的问题排查过程

朋友弄了一个小项目,要我帮忙做下 Linux 系统运维,上线一段时间后,发现项目偶尔会挂掉导致服务不可用。开发朋友一时之间也没空去研究项目奔溃的根因,只好由我这...

43330
来自专栏编程坑太多

springboot(16)Shiro

30560
来自专栏张戈的专栏

修改Apache的超时设置,解决长连接请求超时问题

某日,组内后台开发找到我,问我们的 WEB 服务器超时设置是多少。他反馈的问题是,有一个 VLAN 切换任务 cgi 接口经常返回 504 网关超时错误,要我分...

1.4K80

扫码关注云+社区

领取腾讯云代金券