Shiro官方文档翻译——Apache Shiro的十分钟教程

  • 2019 年 10 月 30 日
  • 筆記

10 Minute Tutorial on Apache Shiro

Introduction

Welcome to Apache Shiro’s 10 Minute Tutoral!

By going through this quick and simple tutorial you should fully understand how a developer uses Shiro in their application. And you should be able to do it in under 10 minutes.

介绍 欢迎来到Apache Shiro十分钟教程 通过这个快速简短的教程,你应该充分明白一个开发者在他们的应用中如何使用Shiro。你们应该能做10分钟内完成这些。

Overview

What is Apache Shiro?

Apache Shiro is a powerful and easy to use Java security framework that offers developers an intuitive yet comprehensive solution to authentication, authorization, cryptography, and session management.

In practical terms, it achieves to manage all facets of your application’s security, while keeping out of the way as much as possible. It is built on sound interface-driven design and OO principles, enabling custom behavior wherever you can imagine it. But with sensible defaults for everything, it is as “hands off” as application security can be. At least that’s what we strive for.

What can Apache Shiro do?

A lot . But we don’t want to bloat the QuickStart. Please check out our Features page if you’d like to see what it can do for you. Also, if you’re curious on how we got started and why we exist, please see the Shiro History and Mission page.

Ok. Now let’s actually do something!

概述 Apache Shiro是什么? Apache Shiro是一个功能强大、易用的java完全框架,它向开发者对认证、授权、密码和session管理提供一个的直观、全面的解决方案。 实际上,它实现了你的应用程序上所有安全方面的管理,并尽可能避免后门。它建立在良好的接口驱动设计和OO原则的基础上,在您可以想象的地方启用自定义行为。但是如果什么都用合理的默认配置,它的安全就像一个“放开手”的系统。至少这是我们的努力目标。 Apache Shiro能做什么? 许多。但是我们不想让"快速入门"变得臃肿。如果你想看看shiro能为你做些什么,请点击我们的功能页面。当然,如果你好奇我们是怎么开始,为什么我们会存在,请看 Shiro History and Mission页面。 好的,现在让我们实际上做点什么!

Note Shiro can be run in any environment, from the simplest command line application to the biggest enterprise web and clustered applications, but we'll use the simplest possible example in a simple main method for this QuickStart so you can get a feel for the API.

注意 Shiro可以在任何环境运行,包括小的命令行程序到大的企业web和集群程序。但是我们将用一个最简单的main方法作为教程的例子,你可以通过这个main方法感受这个API。

Download

1.Ensure you have JDK 1.6+ and Maven 3.0.3+ installed.

2.Download the lastest “Source Code Distribution” from the Download page. In this example, we’re using the 1.3.2 release distribution.

3.Unzip the source package:

下载 1.确保安装jdk1.6+和maven3.0.3+2.从下载页面最后的“Source Code Distribution”下载。在这个例子中,我们会使用发行版1.3.2.3.unzip源码包

   $ unzip shiro-root-1.3.2-source-release.zip

4.Enter the quickstart directory:

进入QuickStart文件夹下

   $ cd shiro-root-1.3.2/samples/quickstart

5.Run the QuickStart:

运行QuickStart

   $ mvn compile exec:java

This target will just print out some log messages to let you know what is going on and then exit. While reading this quickstart, feel free to look at the code found under samples/quickstart/src/main/java/Quickstart.java. Change that file and run the above mvn compile exec:java command as often as you like.

它会打印一些让你知道它进入和离开的日志信息。当阅读quickstart源码时,请找到以下类并阅读samples/quickstart/src/main/java/Quickstart.java。修改文件并重新运行mvn compile exec:java,看看打印结果是否与你预想一致。

个人备注 实际上也可以访问http://shiro.apache.org/download.html,下载Source Code Distribution。里面有个simples的文件夹,QuickStart就在里面。 或使用git下载源码 git clone https://github.com/apache/shiro.git git checkout shiro-root-1.3.2 -b shiro-root-1.3.2

QuickStart.java

The Quickstart.java file referenced above contians all the code that will get you familiar with the API. Now lets break it down in chunks here so you can easily understand what is going on.

In almost all environments, you can obtain the currently executing user via the following call:

QuickStart.java文件包含的所有代码能让你熟悉API。现在让我们把它来便于你更容易的理解它们发生了什么。 在几乎所有的环境中,你可以通过以下调用来获得当前执行的用户

Subject currentUser = SecurityUtils.getSubject();

Using SecurityUtils.getSubject(), we can obtain the currently executing Subject .A Subject is just a security-specific "view" of an application User. We actually wanted to call it 'User' since that "just makes sense", but we decided against it: too many applications have existing APIs that already have their own User classes/frameworks, and we didn't want to conflict with those. Also, in the security world, the term Subject is actually the recoginzed nomenclature. Ok moving on..

The getSubject() call in a standalone application might return a Subject based on user data in an application-specific location, and in a server environment(e.g web app), it acquires the Subject based on user data associated with current thread or incoming request.

Now that you have a Subject, what can you do with it?

If you want to make things available to the user during their current session with the application, you can get their session:

使用SecurityUtils.getSubject(),我们可以过得当前执行的Subject。一个Subject是一个程序用户的特定于安全性的“视图”。事实上,我们叫它'User'自从它"是有意义的",但是我们决定反对这种做法: 许多应用都已经有了用户类/框架的现有API, 我们不想与它们发生冲突。而且,在安全性的世界里,术语Subject事实上就是公认的术语。好的,继续… 在一个独立的应用程序中调用getSubject()方法会返回一个基于本地具体应用程序的用户数据的Subject,并在服务器环境中(例如web应用程序),它基于当前线程的用户信息或传入request的用户信息获得Subject。 现在你有了一个Subject,你能拿它做什么呢? 如果你想要对该应用程序的当前线程做一些有关用户的验证,你可以获得它们的线程:

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

The Session is a Shiro-specific instance that provides most of what you're used to with regular HttpSessions but with some extra goodies and one big difference: it does not require an HTTP environment!

If deploying inside a web application, by default the Session will be HttpSession based. But, in a non-web environment, like this simple Quickstart, Shiro will automatically use its Enterprise Session Management by default. This means you get to use the same API in your applications, in any tier, regardless of deployment environment. This opens a whole new world of applications since any application requiring sessions does not need to be forced to use the HttpSession or EJB Stateful Session Beans. And, any client technology can now share session data.

So now you can acquire a Subject and their Session. What about the really useful stuff like checking if they are allowed to do things, like checking against roles and permissions?

Well, we can only do those checks for a know user. Our Subject instance above represents the current user, but who is the current user? Well, they're anonymous – that is, until they log in at least once. So, let's do that:

这个Session是一个具体的Shiro实例对象,它提供几乎所有你以前使用的合格的HttpSession,但是包含额外的好东西和一个大的不同点:它不会要求一个HTTP环境! 如果部署在一个web应用程序中,默认情况下,Session将是HttpSession的基础。但是,在一个非web环境下,比如这个简单的Quickstart例子,Shiro 将自动使用它默认的企业Sesson管理者。这意味这你在你的应用程序中使用相同的API,在任何层,与开发环境无关。这将打开一个新世界,整个应用程序的任何应用程序需要的Session不需要强迫使用HttpSession或EJB Stateful Session Beans. 同时,任何技术的客户端都可以分享这个Session数据。 现在你可以获得一个Subject和它的Session。真正有用的东西是什么,比如检查他们是否允许去做事情,比如检查它的角色和权限? 好的,我们可以对一个已知的用户做下面的检查。我们上面的Subject实例代表当前用户,但是谁是当前用户?好的,它们是匿名的,直到它们至少登陆一次。所以,让我们做以下代码:

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

That's it! It couldn't be easier.

But what if their login attempt fails?You can catch all sorts of specific exceptions that tell you exactly what happened and allows you to handle and react accordingly:

这就是它的代码!它不能再简单了。 但是如果它们登陆尝试失败会怎么样呢?你可以捕获所有有序的详细的Exceptions,它们会精确的告诉你发生了什么,并允许你处理和做出相应反应:

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

There are many different types of exceptions you can check, or throw you own for custom conditions Shiro might not account for. See the AuthenticationException JavaDoc for more.

这里你可以捕获一些不同类型的异常,或者抛出你自己自定义条件——shiro可能没有考虑到。查看AuthenticationException JavaDoc了解更多。

Handy Hint Security best practice is to give generic login failure messages to users because you do not want to aid an attacker trying to break into yout system.

温馨提示 Security最好的联系是向用户提供通用的登陆失败消息,因为你不想帮助攻击者打破并进入你的系统。

Ok, so by now, we have a logged in user. What else can we do?

Let's say who the are:

ok, 所以我们现在有一个已登陆的用户。我们还能做别的什么吗? 让我们看看它是谁:

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

We can also test to see if they have specific role or not:

我们也能测试它是否有具体的权限,并查看它的权限:

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

We can alse see if they have a permission to act on a certain type of entity:

我们还可以看看他们是否有权对某一类型的实体采取行动:

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.");  }

Also, we can perform an extremely powerful instance-level permission check – the ability to see if the user has the ability to access a specific instance of a type:

并且,我们能执行一个极端的强大的实例级的许可验证,查看用户是否有能力去访问某个特定实例的能力。

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!");  }

Piece of cake, right?

Finally, when the user is done using the application, they can log out:

小菜一碟,是吧? 最后,当用户完成对应用程序的使用时,他们能被注销:

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

Well, that's the core to using Apache Shiro at the application-developer level. And although there is some pretty sophisticated stuff going on under the hood to make this work so elegantly, that's really all there is to it.

But you might ask yourself, "But who is responsible for getting the user data during a login (usernames and passwords, role and permissions, etc), and who actually performs those security checks during runtime?" Well, you do, by implementing what Shiro calls a Realm and plugging that Realm into Shiro's configuration.

However, how you configure a Realm is largely dependent upon your runtime environment. For example, if you run a standalone application, or combination thereof. That type of configuration is outside the scope of this QuickStart, since its aim is to get you comfortable with the API and Shiro's concepts.

When you're ready to jump in with a little more detail, you'll definitely want to read the Authentication Guide and Authorization Guide. Then can move onto other Documentation, in particularly the Reference Manual, to answer any other questions. You'll also probably want to join the user mailing list – you'll find that we have a great community with people willing to help whenever possible.

Thanks for following along. We hope you enjoy using Apache Shiro!

好的,这是应用程序开发者使用Apache Shiro的核心。虽然有一些相当复制的东西被遮盖了,使得工作如此优雅,这就是它们的全部。 但是你应该问问自己,“但是,在整个登陆过程中,谁负责获得用户数据(用户名和密码,角色和权限,等等),在运行过程中,谁实际上执行这些安全验证?”好的,你这么做了,通过实施Shiro调用Realm数据库,和把Realm插入到Shiro的配置中。 然而,怎么去配置Shiro在很大程度上取决于你的运行环境。举个例子,如果你运行一个单独的应用程序,或者如果你有一个基于web的应用程序,或者一个基于Spring或JEE容器的应用程序,或者以上情况都结合在一起。这种配置在这篇QuickStart范围外,因为它(QuickStart)的目的是让你熟悉API和Shiro的概念。 当你准备进入更多的细节的时候,你一定要阅读Authentication Guide(认证指南)和Authorization Guide(授权指南)。接着才可以去阅读其他文档,特别是Reference Manual(参考手册),去解答任何的其他问题。你还可能想要加入用户邮箱列表 – 你会发现我们有一个伟大的社区,只要有困难,大家都愿意帮忙。 谢谢大家的支持。我们希望您能喜欢使用Apache Shiro!