本文为翻译文,原文地址:http://shiro.apache.org/10-minute-tutorial.html

介绍

欢迎来到Apache Shiro的10分钟教程!

通过这个教程,你会明白一个开发人员如何在他们的应用中使用Shiro,并且你也能够在10分钟内做到。

概述

什么是Apache Shiro?

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

Apache Shiro能做什么事情?

它能做很多事情。不过我们不想在入门阶段就全部展开。如果你想知道它能帮你做什么,请查阅我们专门描述特性的网页。如果你好奇我们的起源和为什么我们存在,请查阅描述我们的历史和任务的网页

好了,现在我们开始吧。

  1. 请注意:
  2. Shiro能运行在任何环境,无论简单的命令行,抑或大型的Web应用集群,不过我们在此快速入门会用最简单的例子,比如Javamain方法。这样,你就能了解这些API

下载

  1. 保证已经安装JDK1.6+、Maven3.0.3+
  2. 下载页下载最新的“Source Code Distribution”。在本例中,我们使用1.3.2 release distribution。
  3. 解压
  1. $ unzip shiro-root-1.3.2-source-release.zip
  1. 进入quickstart目录
  1. $ cd shiro-root-1.3.2/samples/quickstart
  1. 运行QuickStart
  1. $ mvn compile exec:java

它的目标只是打印一些日志信息让我们知道这过程中发生了什么,然后退出。在阅读本快速入门,随时查阅代码samples/quickstart/src/main/java/Quickstart.java。尝试改变文件,再运行以上的命令mvn compile exec:java,观察修改的效果。

Quickstart.java

上述的Quickstart.java文件包含我们需要熟悉的API,现在我们分块来看,使我们更容易理解这究竟发生了什么。

在几乎所有的环境中,你能通过以下代码获取当前执行操作用户:

  1. Subject currentUser = SecurityUtils.getSubject();

使用SecurityUtils.getSubject(),我们能获取当前执行操作的SubjectSubject可看作只是一个应用程序的用户的视图。其实我们想叫它“用户”,这样显得更“有意义”,但我们最后还是没这么做。因为太多的应用存在他们自己的User类或框架,我们不想与之发生冲突。另外,在安全的领域里,这个词实际上是公认的术语。

在独立的应用中使用getSubject(),它可能返回一个相应应用的用户,如果在一个服务器环境(比如Web应用),它在当前线程或传入的请求中查找关联的用户。

现在,你有了Subject实例,你能够做什么事情呢?

如果你想使某些东西在应用的当前会话中都可用的,你可以先获取Session,把需使用的东西放入Session中,使用时再取出来:

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

Session是Shiro指定的实例,它提供了大部分我们常用的HttpSession的功能,但它还会有一些额外的好处,和一个重大的区别:它不需要一个HTTP环境!

如果部署在Web应用中,默认情况下Session就是HttpSession。但是,如果在非Web应用中,比如上面的Quickstart.java,Shiro会自动地使用它企业级会话管理。这意味着,无论在任何环境,你都可以使用相同的API操作Session。这打开了一个全新的世界,因为任何应用程序需要会话,不需要强制使用HttpSession或EJB有状态的Session Bean。并且,任何客户端技术可以共享会话数据。

现在我们能获取用户和会话了。有真正有用的事情吗?比如检查他们是否被允许做这个事情?比如检查角色和权限?

好,我们对用户做这些检查。我们上述的Subject代表当前用户,但当前用户是谁呢?他们是匿名的,直到他们至少登录了一次。所以,我们做一次登录吧:

  1. if ( !currentUser.isAuthenticated() ) {
  2. //collect user principals and credentials in a gui specific manner
  3. //such as username/password html form, X509 certificate, OpenID, etc.
  4. //We'll use the username/password example here since it is the most common.
  5. //(do you know what movie this is from? ;)
  6. UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
  7. //this is all you have to do to support 'remember me' (no config - built in!):
  8. token.setRememberMe(true);
  9. currentUser.login(token);
  10. }

就是这样!但它并不简单。

但如果他们登录失败呢?你能捕获各种具体的异常,这些异常能告诉你究竟发生了什么,你可以根据这些做出响应的处理:

  1. try {
  2. currentUser.login( token );
  3. //if no exception, that's it, we're done!
  4. } catch ( UnknownAccountException uae ) {
  5. //username wasn't in the system, show them an error message?
  6. } catch ( IncorrectCredentialsException ice ) {
  7. //password didn't match, try again?
  8. } catch ( LockedAccountException lae ) {
  9. //account for that username is locked - can't login. Show them a message?
  10. }
  11. ... more types exceptions to check if you want ...
  12. } catch ( AuthenticationException ae ) {
  13. //unexpected condition - error?
  14. }

你可以处理不同类型的异常,或者为特定的情况抛出自定义的异常。更详细的请见用户验证文档

  1. 方便的提示:
  2. 当用户登录失败,较安全的方式是给予常规的模糊的提示,比如登录失败,因为我们不希望提示信息帮忙攻击者尝试攻击我们的系统。

好,现在我们有一个登录用户。我们还能做什么?

比如说他们是谁?

  1. //print their identifying principal (in this case, a username):
  2. log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." );

我们还可以测试他们是否有指定的角色:

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

我们也可以测试他们是否有指定的权限:

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

我们可以执行一个非常强大的实例级权限检查,用户是否有权限访问指定类型的实例:

  1. if ( currentUser.isPermitted( "winnebago:drive:eagle5" ) ) {
  2. log.info("You are permitted to 'drive' the 'winnebago' with license plate (id) 'eagle5'. " +
  3. "Here are the keys - have fun!");
  4. } else {
  5. log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
  6. }

很容易,对吗?

最后,当用户使用系统完毕时,他们可以注销:

  1. currentUser.logout(); //removes all identifying information and invalidates their session too.

这是开发人员使用Apache Shiro的核心的基础的知识,虽然一些很复杂的逻辑隐藏在引擎盖下面。

你可能会问自己,在登录时,谁负责获取用户的数据(用户名、密码、角色、权限等)?在程序运行时谁执行这些检查?恩,你做,通过实现Shiro中称为Realm的东西,并注册该Realm到Shiro的配置中。

然而,如何配置一个Realm很大程度上依赖于运行环境。比如,如果你运行一个独立的应用,或者是Web应用,又或者是Spring应用,或J2EE应用,再或者它们的合并体。这种类型的配置在此快速入门的范围之外,因为此快速入门的目的仅是让我们熟悉API和Shiro的概念。

当你准备跳入更多细节,你一定会想要阅读身份验证指南授权指南。然后可以移动到其它文档,特别是参考手册,去了解各种其它问题。你可能会想加入用户邮件列表,你会发现我们有一个热情的社区。

感谢您的阅读。我们希望你享受使用Apache Shiro!

【翻译】Apache Shiro10分钟教程的更多相关文章

  1. Tips & Tricks:Apache log4j简明教程(一)

    Apache log4j的官方介绍是“log4j is a reliable, fast and flexible logging framework (APIs) written in Java, ...

  2. Git之2分钟教程

    Git之2分钟入门 普通人:“借我1000块钱”.程序猿:“借你1024吧,凑个整”. 今天是1024,是我们程序员的节日,在此,首先祝各位程序猿以及程序媛们节日快乐~然后送出一份节日礼物,没错,就是 ...

  3. Org-mode五分钟教程ZZZ

    Table of Contents 1 源起 2 简介 2.1 获取 org-mode 2.2 安装 3 基础用法 3.1 创建一个新文件 3.2 简单的任务列表 3.3 使用标题组织一篇文章 3.4 ...

  4. [个人翻译]Redis 集群教程(中)

    上一篇:http://www.cnblogs.com/li-peng/p/6143709.html 官方原文地址:https://redis.io/topics/cluster-tutorial  水 ...

  5. CentOS6.0(64位)安装Apache+PHP+Mysql教程,安装Magento(解决DOM,Mcrypt,GD问题)完整教程

    CentOS6.0(64位)安装Apache+PHP+Mysql教程,安装Magento(解决DOM,Mcrypt,GD问题)完整教程 0   Posted by :小黑 On : 2012 年 9 ...

  6. 【项目管理和构建】十分钟教程,eclipse配置maven + 创建maven项目(三)

    [项目管理和构建]十分钟教程,eclipse配置maven + 创建maven项目(三) 上篇博文中我们介绍了maven下载.安装和配置(二),这篇博文我们配置一下eclipse,将它和maven结合 ...

  7. [转载]GDB十分钟教程

    转自:http://blog.csdn.net/liigo/article/details/582231/ GDB十分钟教程 作者: liigo原文链接: http://blog.csdn.net/l ...

  8. JUnit三分钟教程 ---- 实际应用

    JUnit三分钟教程 ---- 实际应用 摘自http://lavasoft.blog.51cto.com/62575/65775   接上文"JUnit三分钟教程 ---- 快速起步&qu ...

  9. JUnit三分钟教程 ---- 快速起步

    JUnit三分钟教程 ---- 快速起步 摘自http://lavasoft.blog.51cto.com/62575/65625/ JUnit是个好东西,做大点的项目离不开这东西,实际中用的时候也因 ...

随机推荐

  1. 牛客练习赛35-函数的魔法-floyd

    函数的魔法 思路 :如果 可以从A到B最终 都会是233范围内的数字进行转换,注意 这里 建图 为单向图  这个运算未必符合交换关系. #include<bits/stdc++.h> us ...

  2. python 列表常用操作(二)

    1.tuple 的 unpack a,b = t 2.格式化输出 print('您的输入:{},值为{}',format(a,b)) 3.日期计算 import datetime as dt impo ...

  3. 进程篇:wait & waitpid

    #include <sys/types.h> /* 提供类型pid_t的定义 */ #include <sys/wait.h> pid_t wait(int *status) ...

  4. POJ.2175.Evacuation Plan(消圈)

    POJ \(Description\) \(n\)个建筑物,每个建筑物里有\(a_i\)个人:\(m\)个避难所,每个避难所可以容纳\(b_i\)个人. 给出每个建筑物及避难所的坐标,任意两点间的距离 ...

  5. python基础一 ------linux某目录下批量的为特定文件加入可执行权限

    需求: 一个文件夹中有个文件,要求对特定的文件加入可执行权限 某文件系统目录下有一系列文件:    quicksort    graph.py    heap.java    install.sh   ...

  6. centos下python安装与虚拟环境配置

    Centos7下安装Python3.7 首先安装依赖包,centos里面是-devel,如果在ubuntu下安装则要改成-dev,依赖包缺一不可,笔者曾安装python3未成功就是因为没有安装libf ...

  7. 20172310 实验四 Android程序设计

    20172310 2017-2018-2 <程序设计与数据结构>实验四报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 仇夏 学号:20172310 实验教师:王志 ...

  8. python系统编程(九)

    同步的概念 1. 多线程开发可能遇到的问题 假设两个线程t1和t2都要对num=0进行增1运算,t1和t2都各对num修改10次,num的最终的结果应该为20. 但是由于是多线程访问,有可能出现下面情 ...

  9. HttpClient异步调用引发的程序挂起问题排查及解决

    在搭建搭建分布式系统时,基础组件与框架的重要性不言而喻.但是如果组件出现bug,真的很要命.虽然我们通过各种单元测试,拼命找bug,但是总有一些问题被盲目自信蒙蔽了双眼,很多时候我们认为这段代码100 ...

  10. 键盘回收(text filed,textview)

    键盘回收 #pragma mark - TextField 代理方法 - (BOOL)textFieldShouldReturn:(UITextField *)textField { [self.vi ...