Apache Shiro 10分钟教程

Apache Shiro 10分钟教程

参考:10 Minute Tutorial on Apache Shiro

介绍

欢迎来到Apache Shiro的10分钟教程。通过学习这个快速而简单的教程,您应该能完全理解开发人员如何在应用程序中使用Shiro。

概述

Apache Shiro 是什么?

Apache Shiro 是一个功能强大且易于使用的 Java 安全框架,它为开发人员提供了一个直观而全面的身份验证、授权、加密和会话管理解决方案。

实际上,Apache Shiro可以管理应用程序安全性的各个方面,同时尽可能避免干扰。它建立在合理的接口驱动设计和OO原则之上,可以在任何你能想到的地方实现自定义行为。但是由于对所有内容都有合理的默认值,应用安全尽可能做到“放得开手”。至少这是我们努力的目标。

Apache Shiro 能做什么?

很多。但是我们不想让快速入门变得臃肿。如果您想了解它能为您做什么,请查看我们的功能页面。此外,如果您对我们是如何开始的以及我们存在的原因感到好奇,请参阅Shiro历史和任务页面。

好的,现在让我们真正做点什么!

注意:在本快速入门中,我们将在一个简单的 main 方法中使用最简单的示例,以便您可以了解 API。

下载

  1. 确保安装了JDK 1.8+和Maven 3.0.3+。
  2. 从下载页面下载最新的“源代码分发”。在此示例中,我们使用的是 1.10.1 版本发行版。
  3. 解压缩源码包:unzip shiro-root-1.10.1-source-release.zip
  4. 进入快速入门目录:cd shiro-root-1.10.1/samples/quickstart
  5. 运行快速入门:mvn compile exec:java

这个目标只会打印一些日志消息,让您知道发生了什么,然后退出。阅读本快速入门时,请随时查看 samples/quickstart/src/main/java/Quickstart.java下的代码。修改该文件并根据需要随时运行mvn compile exec:java命令。

Quickstart.java

在几乎所有环境中,您都可以通过以下调用获取当前正在执行的用户:

Subject currentUser = SecurityUtils.getSubject();

Subject主体只是应用程序用户的特定安全“视图”。我们实际上想称它为“User”,因为这“含义更明确”,但我们决定不这样做:太多的应用程序都有自己的User类或框架的现有API,我们不想与这些API冲突。此外,在安全领域,术语 Subject 实际上是公认的命名法。

独立应用程序中的getSubject()调用可能根据应用程序特定位置中的用户数据返回一个Subject,在web应用等服务器环境中,它根据与当前线程或传入请求相关联的用户数据获取Subject。

有了Subject,你可以用它做什么?

如果想让内容在用户与应用的当前会话中对用户可用,您可以获取他们的会话:

Session session = currentUser.getSession();
session.setAttribute( "someKey", "aValue" );

Session是特定于 Shiro 的实例,它提供了您习惯于常规 HttpSession 的大部分内容,但有一些额外的好处和一个很大的区别:它不需要 HTTP 环境!

如果部署在web应用程序中,默认情况下Session将是基于HttpSession的。但是,在非 Web 环境中,就像此简单快速入门,Shiro 默认情况下将自动使用其企业会话管理。这意味着无论部署环境如何,您都可以在任何层的应用程序中使用相同的 API。这打开了一个全新的应用程序世界,因为任何需要会话的应用程序都不需要强制使用HttpSession或EJB有状态会话Bean。而且,任何客户端技术现在都可以共享会话数据。

那些真正有用的东西要怎样呢,比如检查是否被允许做一些事情,比如检查角色和权限?

我们只能对已知用户进行这些检查。上面的Subject实例表示当前用户,但谁是当前用户?好吧,他们是匿名的,直到他们至少登录一次。所以,让我们开始吧。

if ( !currentUser.isAuthenticated() ) {
    UsernamePasswordToken token = new UsernamePasswordToken("uname", "passwd");
    token.setRememberMe(true);
    currentUser.login(token);
}

就是这样!再容易不过了。

但是如果登录尝试失败了怎么办?您可以捕获各种特定的异常,这些异常告诉您究竟发生了什么,并允许您进行相应的处理和反应。

try {
    //如果没有例外,我们就完成了
    currentUser.login( token );
} catch ( UnknownAccountException uae ) {
    //用户名不在系统中,向他们显示错误消息?
} catch ( IncorrectCredentialsException ice ) {
    //密码不匹配,请重试?
} catch ( LockedAccountException lae ) {
    //该用户名的帐户已锁定—无法登录。向他们显示相应信息?
} catch ( AuthenticationException ae ) { //如果需要,可以检查更多类型的异常
    //意外情况-错误?
}

您可以检查许多不同类型的异常,或者为Shiro可能无法解释的自定义条件抛出自己的异常。

提示:安全最佳实践是向用户提供一般的登录失败消息,因为您不希望帮助攻击者试图闯入您的系统。

现在,我们有了一个登录用户。我们还能做什么?让我们说下他们是谁。

//打印其标识主体(在本例中为用户名)
log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." );

我们还可以测试他们是否具有特定角色:

if ( currentUser.hasRole( "schwartz" ) ) {
    log.info("May the Schwartz be with you!" );
} else {
    log.info( "Hello, mere mortal." );
}

我们还可以查看他们是否拥有对某种类型的实体进行操作的权限:

if ( currentUser.isPermitted( "lightsaber:wield" ) ) {
    log.info("You may use a lightsaber ring. Use it wisely.");
} else {
    log.info("Sorry, lightsaber rings are for schwartz masters only.");
}

此外,我们还可以执行非常强大的实例级权限检查—查看用户是否具有访问某种类型的特定实例的能力:

if ( currentUser.isPermitted( "winnebago:drive:eagle5" ) ) {
    log.info("允许你驾驶(drive)车牌号为eagle5的winnebago。这是钥匙,玩得开心!");
} else {
    log.info("对不起,你不允许驾驶eagle5 winnebago");
}

小菜一碟,对吧?最后,当用户使用完应用程序后,他们可以登出:

//删除所有标识信息并使其会话失效
currentUser.logout();

以上就是在应用程序开发人员级别使用Apache Shiro的核心。尽管引擎盖下有一些非常复杂的东西使这项工作如此优雅,但这就是它的全部内容。

但是您可能会问自己,“谁负责在登录期间获取用户数据(用户名和密码、角色和权限等),谁在运行时实际执行这些安全检查?” 您可以通过实现Shiro所谓的Realm并将该Realm插入到Shiro的配置中来实现。

然而,如何配置Realm(Realm .html)很大程度上取决于您的运行时环境。Web等类型的配置超出了本快速入门的范围,因为它的目标是让您熟悉API和Shiro的概念。

当您准备了解更多细节时,一定要阅读身份验证指南(Authentication)和授权指南(Authorization)。然后可以转到其他文档,特别是参考手册,以回答任何其他问题。您可能还想加入用户邮件列表—您会发现我们有一个很棒的社区,人们愿意尽可能提供帮助。

感谢您的关注。我们希望您喜欢使用Apache Shiro!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值