# 20. 10 Minute Tutorial 十分钟教程
# 20. 10 Minute Tutorial 十分钟教程
## Introduction 前言
欢迎来到 Apache Shiro 十分钟教程!
希望通过这个简单、快速的示例,可以让你对应用程序中使用 Shiro 有个深入的了解。嗯,10分钟你应该可以搞定它。
## Overview 概述
Apache Shiro 是什么?
Apache Shiro 一个功能强大,使用简单的 Java 安全框架,它为开发人员提供一个直观而全面的认证,授权,加密及会话管理的解决方案。
实际上,Shiro 的主要功能是管理应用程序中与安全相关的全部,同时尽可能支持多种实现方法。Shiro 是建立在完善的接口驱动设计和面向对象原则之上的,支持各种自定义行为。Shiro 提供的默认实现,使其能完成与其他安全框架同样的功能,这不也是我们一直努力想要得到的吗!
那么 Apache Shiro 能用来做什么呢?
很多,很多,嘿嘿。但是不在快速指南中做介绍,如果你想知道,那怎么办呢?去[这里](http://shiro.apache.org/features.html)找寻你的答案吧。当然如果你还想知道我们什么时候,以及为什么要“创造”Shiro,去看看Shrio的[历史和使命](http://shiro.apache.org/what-is-shiro.html)吧。
现在让我们动手做点儿什么吧。
*Shiro可以在任何环境下运行,小到最简单的命令行应用,大到大型的企业应用以及集群应用。但是我们准备在快速指南中使用最最简单的 main 方法的方式,让你对 Shiro 的API有个感官的认识。*
## Download 下载
1. 确保已经安装了 JDK1.5+ 和 Maven2.2+
2. 去这里[下载](http://shiro.apache.org/download.html)最新已发布的源码。例子中我们使用 1.1.0 发布版本。
3. 解压源代码
unzip shiro-root-1.2.0-source-release.zip
4. 进入快速指南文件夹
cd shiro-root-1.1.0/samples/quickstart
5. 运行快速指南
mvn compile exec:java
过程中会输出日志信息,用来告诉你正在进行的是什么,最后退出执行。可以在这里 samples/quickstart/src/main/java/Quickstart.java 找到源码,也可以进行修改,记得修改后运行 mvn compile exec:java 即可。
## Quickstart.java
Quickstart.java 中包含刚刚我们提到的所有内容(认证、授权等等),通过这个简单的示例可以让你轻松的熟悉Shiro的API。那么,让我们把Quickstart.java中的代码,一点一点剖析,这样便于理解它们的作用。 几乎所有的环境下,都可以通过这种方式获取当前用户:
```
Subject currentUser = SecurityUtils.getSubject();
```
通过 [SecurityUtils.getSubject()](http://shiro.apache.org/static/current/apidocs/org/apache/shiro/SecurityUtils.html),就可以获取当前 [Subject](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/IV.%20Auxiliary%20Support%20%E8%BE%85%E5%8A%A9%E6%94%AF%E6%8C%81/14.%20Custom%20Subjects%20%E8%87%AA%E5%AE%9A%E4%B9%89%20Subject.md)。Subject 是应用中用户的一个特定安全的缩影,虽然感觉上直接使用 User 会更贴切,但是实际上它的意义远远超过了 User。而且每个应用程序都会有自己的用户以及框架,我们可不想和它们混淆在一起,况且 Subject 就是安全领域公认的名词。OK,我们继续。
在单应用系统中,调用 getSubject() 会返回一个 Subject,它是位于应用程序中特定位置的用户信息;在服务器中运行的情况下(比如web应用),getSubject 会返回一个位于当前线程或请求中的用户信息。 现在你已经得到了 Subject 对象,那么用它可以做什么呢?
如果你想得到应用中用户当前 Session 的其他参数,可以这样获取Session 对象:
```
Session session = currentUser.getSession();
session.setAttribute( "someKey", "aValue" );
```
这个Session 对象是Shiro中特有的对象,它和我们经常使用的HttpSession 非常相似,但还提供了额外的东西,其中与 HttpSession最大的不同就是 Shiro 中的 Session 不依赖 HTTP 环境(换句话说,可以在非 HTTP 容器下运行)。
如果将 Shiro 部署在 web 应用程序中,那么这个 Session 就是基于HttpSession 的。但是像 QuickStart 示例那样,在非 web 环境下使用,Shiro 则默认使用 EnterpriseSessionManagment。也就是说,不论在应用中的任何一层使用同样的API,却不需要考虑部署环境,这一优点为应用打开一个全新的世界,因为应用中要获取Session对象再也不用依赖于 HttpSession 或者 EJB 的会话 Bean。而且任何客户端技术都可以共享 session 数据。
现在你可以得到当前 Subject 和它的 Session 对象。那么我们如何验证比如角色和权限这些东西呢?
很简单,可以通过已得到的 user 对象进行验证。Subject 对象代表当前用户,但是,谁才是当前用户呢?他们可是匿名用户啊。也就是说,必须登录才能获取到当前用户。没问题,这样就可以搞定:
```
if ( !currentUser.isAuthenticated() ) {
//收集用户的主要信息和凭据,来自GUI中的特定的方式
//如包含用户名/密码的HTML表格,X509证书,OpenID,等。
//我们将使用用户名/密码的例子因为它是最常见的。.
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
//支持'remember me' (无需配置,内建的!):
token.setRememberMe(true);
currentUser.login(token);
}
```
就是这样,不能再简单了。
但如果登录失败了呢,你可以捕获所有异常然后按你期望的方式去处理:
```
try {
currentUser.login( token );
//无异常,说明就是我们想要的!
} catch ( UnknownAccountException uae ) {
//username 不存在,给个错误提示?
} catch ( IncorrectCredentialsException ice ) {
//password 不匹配,再输入?
} catch ( LockedAccountException lae ) {
//账号锁住了,不能登入。给个提示?
}
... 更多类型异常 ...
} catch ( AuthenticationException ae ) {
//未考虑到的问题 - 错误?
}
```
这里有许多不同类别的异常你可以检测到,也可以抛出你自己异常。详见 [AuthenticationException JavaDoc](http://shiro.apache.org/static/current/apidocs/org/apache/shiro/authc/AuthenticationException.html)
*小贴士:*
*最好的方式是将普通的失败信息反馈给用户,你总不会希望帮助黑客来攻击你的系统吧。*
好,到现在为止,我们有了一个登录用户,接下来我们还可以做什么?
让我们显示他们是谁
```
//打印主要信息 (本例子是 username):
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:weild" ) ) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
```
同样,我们还可以执行非常强大的 instance-level (实例级别)的权限检测,检测用户是否具备访问某个类型特定实例的权限:
```
if ( currentUser.isPermitted( "winnebago:drive:eagle5" ) ) {
log.info("You are permitted to 'drive' the 'winnebago' with license plate (id) 'eagle5'. " +
"Here are the keys - have fun!");
} else {
log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
}
```
轻而易举,是吧!
最后,当用记不再使用系统,可以退出登录:
```
currentUser.logout(); //清楚识别信息,设置 session 失效.
```
这些就是使用 Apache Shiro 开发应用的核心了,当然,Apache Shiro已将将很多复杂的东西封装在内部了,但是现在它就是这么简单。
你会有疑问吧,用户登录时,谁负责把用户信息(用户名、密码、角色、权限等)取出来,还有运行时,谁负责安全认证呢?当然由你决定了啊。通过将一个实现了 Shiro 中的 [Realm](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/II.%20Core%20%E6%A0%B8%E5%BF%83/7.%20Realms.md) 的 Reaml 配置到 Shiro 中即可。
至于如何配置很大程度上取决于你的运行时环境,比如在单应用、web 应用、基于 Spring 或 JEE 容器的应用或者组合模式中使用 Shiro,配置都有所不同。如何配置已经超出 QuickStart 示例的范围,因为它的主要目的是帮助你熟悉 Shiro 的 API 和概念。
如果想进一步了解 Shiro,可以看看 [Authentication](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/II.%20Core%20%E6%A0%B8%E5%BF%83/5.%20Authentication%20%E8%AE%A4%E8%AF%81.md) Guide 和 [Authorization](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/II.%20Core%20%E6%A0%B8%E5%BF%83/6.%20Authorization%20%E6%8E%88%E6%9D%83.md) Guide。也可以查看其他[文档](http://shiro.apache.org/documentation.html)(特别是 [用户指南](https://github.com/waylau/apache-shiro-1.2.x-reference)),这里可以解决你的各种疑问。
感谢一路同行,希望你能喜欢使用 Apache Shiro。
*译者注:*本文参考:<http://shiro.apache.org/10-minute-tutorial.html>。如果对本中文翻译有疑议的或发现勘误欢迎指正,[点此](https://github.com/waylau/apache-shiro-1.2.x-reference/issues)提问。
- Introduction
- 1. Introduction 介绍
- 2. Tutorial 教程
- 3. Architecture 架构
- 4. Configuration 配置
- 5. Authentication 认证
- 6. Authorization 授权
- 6.1. Permissions 权限
- 7. Realms
- 8. Session Management
- 9. Cryptography 密码
- 10. Web
- 10.1. Configuration 配置
- 10.2. 基于路径的 url 安全
- 10.3. Default Filters 默认过滤器
- 10.4. Session Management
- 10.5. JSP Tag Library
- 11. Caching 缓存
- 12. Concurrency & Multithreading 并发与多线程
- 13. Testing 测试
- 14. Custom Subjects 自定义 Subject
- 15. Spring Framework
- 16. Guice
- 17. CAS
- 18. Command Line Hasher
- 19. Terminology 术语
- 20. 10 Minute Tutorial 十分钟教程
- 21. Beginner's Webapp Tutorial 初学者web应用教程
- 22. Application Security With Apache Shiro 用Shiro保护你的应用安全
- 23. CacheManager 缓存管理
- 24. Apache Shiro Cryptography Features 加密功能