This text is translated text, original address: http://shiro.apache.org/10-minute-tutorial.html
Introduced
Welcome to Apache Shiro's 10-minute tutorial!
With this tutorial, you will fully understand how a developer can use Shiro in their applications, and you can do so in 10 minutes.
Overview
What is Apache Shiro?
Apache Shiro is a powerful, easy-to-use Java security framework that provides developers with an intuitive and comprehensive solution for authentication, authorization, encryption, and session management.
What can Apache Shiro do?
A lot. But we don't want to start all in the introductory phase. If you want to know what it can do for you, check out our page describing features. If you are curious about our origins and our existence, please refer to the page describing our history and tasks.
Okay, now let's get started.
请注意:Shiro能运行在任何环境,无论简单的命令行,或者大型的Web集群应用,不过我们在此快速入门会用最简单的例子,比如main方法,这样你就能了解这些API。
Download
- Ensure that jdk1.6+ and maven3.0.3+ are installed
- Download the latest "Source Code distribution" on the download page. In this example, we use the 1.3.2 release distribution.
Extract
$ unzip shiro-root-1.3.2-source-release.zip
Enter the QuickStart directory
$ cd shiro-root-1.3.2/samples/quickstart
Run QuickStart
$ mvn compile exec:java
Its goal is simply to print some log information to let us know what happened and then exit. Read this quick start and check your code at any time samples/quickstart/src/main/java/Quickstart.java
. Try changing the file to run the above command mvn compile exec:java
.
Quickstart.java
The above Quickstart.java
file contains all the APIs that we need to be familiar with, and now we're looking at chunks to make it easier to understand what's going on.
In almost all environments, you can get the current execution user through the following code:
Subject currentUser = SecurityUtils.getSubject();
Use SecurityUtils.getSubject()
, we can get the current execution Subject
. Subject
can be viewed as just a theme view of the user of an application. We actually wanted to call it "user" that seemed "meaningful", but we didn't do it at the end. Because too many applications have their own user classes or frameworks, we are not quite in conflict with them. In addition, in the field of security, the term is actually a worker's term.
Used in standalone applications getSubject()
, it may return a user of a specific application, if in a server environment (such as a web app), it looks for the associated user in the current thread or incoming request.
Now that you have an Subject
object, what can you do about it?
If you want to make something available in the current session of the current app, you can get the session first:
Session session = currentUser.getSession();session.setAttribute( "someKey", "aValue" );
The session is the object specified by Shiro, providing most of the common httpsession that we commonly use, but with some additional benefits and a significant difference: it does not require an HTTP environment!
If deployed in a web app, the session is httpsession by default. However, if you are in a non-web application, such as the above Quickstart.java
, Shiro will automatically use it for enterprise session management. This means that you can use the same API, regardless of the environment. This opens up a whole new world because any application needs a session and does not need to enforce the use of HttpSession or EJB stateful session beans. Also, any client technology can share session data.
Now we can get users and conversations. Is there anything really useful? Like checking if he's allowed to do it? Like checking roles and permissions?
OK, we do these checks for the user. We represent the Subject
current user above, but who is the current user? They are anonymous until they log in at least once. So, let's do a login:
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! But it's not easy.
But what if they fail to log in? You can capture a variety of specific anomalies that can tell you exactly what happened, and you can respond to these responses by handling:
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?}
You can check for different types of exceptions.
方便的提示:当用户登录失败,安全的最佳实践是给与常规的模糊的提示,比如登录失败,因为我们不希望帮忙攻击者尝试攻击我们的系统。
OK, now we have a login user. What else can we do?
For example, who are they?
//print their identifying principal (in this case, a username): log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." );
We can test if they have the specified role:
if ( currentUser.hasRole( "schwartz" ) ) { log.info("May the Schwartz be with you!" );} else { log.info( "Hello, mere mortal." );}
We can test whether they have the specified permissions:
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.");}
We can perform a very powerful check of instance-level permissions and whether users have permission to access specific types of instances:
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!");}
It's easy, right?
Finally, when the user is finished with the system, they can log off:
currentUser.logout(); //removes all identifying information and invalidates their session too.
This is the core knowledge of developers using Apache Shiro, although some very complex logic is hidden underneath the hood.
You may ask yourself, who is responsible for getting the user's data (user name, password, role, permissions, etc.) at the time of login? Who performs these checks while the program is running? Well, you do, by realizing what Shiro says about realm and so on.
However, how to configure a realm is largely dependent on the operating environment. For example, if you run a standalone application, or a Web application, or a spring application, or a Java EE application, or a merge of them. This type of configuration is outside the scope of this QuickStart because the purpose of this QuickStart is to familiarize us with the concepts of APIs and Shiro.
When you are ready to jump into more detail, you will definitely want to read the certification guide and the Licensing Guide. You can then move to a document, especially a reference manual, to learn about a variety of other issues. You may want to join the user mailing list and you will find that we have a passionate community.
Thank you for reading. We want you to enjoy using Apache shiro!
"Translator" Apache Shiro10 minute Tutorial