If you’re new to Apache Shiro, this short tutorial will show you how to set up an initial and very simple application secured by Apache Shiro. We’ll discuss Shiro’s core concepts along the way to help familiarize you with Shiro’s design and API.
如果你是刚开始使用Apache Shiro, 这个简短的教程会教你怎么使用Apache Shiro去建立一个初始的简单的安全应用程序。我们会讨论Shiro的核心概念来帮助你熟悉Shiro的设计和API。
If you don’t want to actually edit files as you follow this tutorial, you can obtain a nearly identical sample application and reference it as you go. Choose a location:
如果你不想在学习这个教程时实际编辑文件,你可以获取一个几乎相同的例子程序来引用。
选择一个地址:
In Apache Shiro’s Git repository: https://github.com/apache/shiro/tree/master/samples/quickstart
Apache Shiro的git仓库:https://github.com/apache/shiro/tree/master/samples/quickstart
In Apache Shiro’s source distribution’s samples/quickstart directory. The source distribution is available from the Download page.
在Apache Shiro源代码发行版的samples/quickstart目录中。源代码发布可以从下载页面获得。
In this simple example, we’ll create a very simple command-line application that will run and quickly exit, just so you can get a feel for Shiro’s API.
这个简单的例子程序,我们会创建一个简单的命令行应用程序来来运行和退出,你可以对Shiro的API有一些了解。
Any Application
Apache Shiro was designed from day one to support any application - from the smallest command-line applications to the largest clustered web applications. Even though we’re creating a simple app for this tutorial, know that the same usage patterns apply no matter how your application is created or where it is deployed.
Apache Shiro 一个始就被设计为支持任何应用程序——从小的命令行应用程序到大型集群web应用程序。尽管这个教程我们创建一个简单的app,但是要知道,相同的使用模式的不管你的应用程序如何创建或者怎么部署都适用。
This tutorial requires Java 1.5 or later. We’ll also be using Apache Maven as our build tool, but of course this is not required to use Apache Shiro. You may acquire Shiro’s .jars and incorporate them in any way you like into your application, for example maybe using Apache Ant and Ivy.
这个教程要求Java1.5或者更高。我们同样使用Apache Maven作为我们的构建工具,当然这不是使用Apache Shiro必须的。你可以获取Shiro.jar并以任何你喜欢的方式包含到你的应用程序中,例如Apache Ant 和 Ivy。
For this tutorial, please ensure that you are using Maven 2.2.1 or later. You should be able to type mvn --version in a command prompt and see something similar to the following:
根据这个教程,请保证你使用的是Maven 2.2.1或者更高。你应该在键入mvn --version命令来查看和下面相似的提示:
Testing Maven Installation
hazlewood:~/shiro-tutorial$ mvn --version
Apache Maven 2.2.1 (r801777; 2009-08-06 12:16:01-0700)
Java version: 1.6.0_24
Java home: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
Default locale: en_US, platform encoding: MacRoman
OS name: “mac os x” version: “10.6.7” arch: “x86_64” Family: “mac”
For now, create a new directory on your filesystem, for example, shiro-tutorial and save the following Maven pom.xml file in that directory:
从现在开始,创建换一个新的文件夹在你的文件系统,例如,shiro-tutorial并且保存下列的Maven pom.xml 文件在这个文件夹中:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>org.apache.shiro.tutorialsgroupId>
<artifactId>shiro-tutorialartifactId>
<version>1.0.0-SNAPSHOTversion>
<name>First Apache Shiro Applicationname>
<packaging>jarpackaging>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>2.0.2version>
<configuration>
<source>1.5source>
<target>1.5target>
<encoding>${project.build.sourceEncoding}encoding>
configuration>
plugin>
<plugin>
<groupId>org.codehaus.mojogroupId>
<artifactId>exec-maven-pluginartifactId>
<version>1.1version>
<executions>
<execution>
<goals>
<goal>javagoal>
goals>
execution>
executions>
<configuration>
<classpathScope>testclasspathScope>
<mainClass>TutorialmainClass>
configuration>
plugin>
plugins>
build>
<dependencies>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-coreartifactId>
<version>1.1.0version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-simpleartifactId>
<version>1.6.1version>
<scope>testscope>
dependency>
dependencies>
project>
The Tutorial class
We’ll be running a simple command-line application, so we’ll need to create a Java class with a public static void main(String[] args)
method.
这个教程会运行一个简单的命令行程序,所以我们需要创建一个带有 public static void main(String[] args)
方法的Java类。
In the same directory containing your pom.xml file, create a *src/main/java sub directory. In src/main/java create a Tutorial.java file with the following contents:
在包含你的pom.xml文件的相同目录下,创建src/main/java文件夹。在src/main/java目录下新建一个包含一下内容的Tutorial.java文件:
src/main/java/Tutorial.java
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tutorial {
private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class);
public static void main(String[] args) {
log.info("My First Apache Shiro Application");
System.exit(0);
}
}
Don’t worry about the import statements for now - we’ll get to them shortly. But for now, we’ve got a typical command line program ‘shell’. All this program will do is print out the text “My First Apache Shiro Application” and exit.
现在不要担心这些导入语句 —— 我们很快就会讲到。但是现在,我们要有一个典型的命令行’shell’程序。这个程序会打印"My First Apache Shiro Application"并且退出。
To try our Tutorial application, execute the following in a command prompt in your tutorial project’s root dirctory (e.g. shiro-tutorial), and type the following:
在你教程工程的根目录执行下列命令提示去尝试运行Tutorial程序:
mvn compile exec:java
And you will see our little Tutorial ‘application’ run and exit. You should see something similar to the following (notice the bold text, indicating our output):
你会看到我们这个小程序运行然后退出。你应该会看到一些类似下列信息的东西(注意粗体文本,表示我们的输出):
Run the Application
运行这个程序:
lhazlewood:~/projects/shiro-tutorial$ mvn compile exec:java
… a bunch of Maven output …
Maven 输出:
1 [Tutorial.main()] INFO Tutorial - My First Apache Shiro Application
lhazlewood:~/projects/shiro-tutorial\$
We’ve verified the application runs successfully - now let’s enable Apache Shiro. As we continue with the tutorial, you can run mvn compile exec:java after each time we add some more code to see the results of our changes.
我们已经核实了程序已经成功的运行 —— 现在让让我们开始Apache Shiro。继续这个教程,你可以在我们每次添加一些代码想看到一个改变结果时运行mvn compile exec:java
The first thing to understand in enabling Shiro in an application is that almost everything in Shiro is related to a central/core component called the SecurityManager. For those familiar with Java security, this is Shiro’s notion of a SecurityManager - it is NOT the same thing as the java.lang.SecurityManager.
在一个应用程序中开启Shiro的第一件要了解的事就是与几乎所有事都相关的核心组件SecurityManager。对于那些熟悉Java安全shur的人来说,这个SecurityManager是Shiro的概念——并不是相同的java.lang.SecurityManager。
While we will cover Shiro’s design in detail in the Architecture chapter, it is good enough for now to know that the Shiro SecurityManager is the core of a Shiro environment for an application and one SecurityManager must exist per application. So, the first thing we must do in our Tutorial application is set-up the SecurityManager instance.
我们会在架构章节讨论有关Shiro的详细设计。现在知道Shiro SecurityManager是一个应用里Shiro环境的核心,并且每一个应用都应该有一个SecurityManager就足够了。所以我们在这个教程中必须要做的第一件事是创建一个SecurityManager的实例。
While we could instantiate a SecurityManager class directly, Shiro’s SecurityManager implementations have enough configuration options and internal components that make this a pain to do in Java source code - it would be much easier to configure the SecurityManager with a flexible text-based configuration format.
我们可以马上实例化一个SecurityManager类,Shiro的SecurityManger实现有许多配置
选项和内部组件,这在java源码中做到这一个是很痛苦的(很难)—— 使用灵活的文本配置格式会使用SecurityManager的配置变得非常简单。
To that end, Shiro provides a default ‘common denominator’ solution via text-based INI configuration. People are pretty tired of using bulky XML files these days, and INI is easy to read, simple to use, and requires very few dependencies. You’ll also see later that with a simple understanding of object graph navigation, INI can be used effectively to configure simple object graphs like the
SecurityManager.
最后,Shiro提供了一个默认的’公分母’(就是那个.ini文件)解决方案经由文本INI配置.人们对使用笨重xml文件已经非常疲惫了,而INI文件容易阅读,使用简单,只需要非常少的依赖。稍后你会看到对对象导图的简单理解,INI可以有效的配置对象图比如SecurityManager。
Shiro’s SecurityManager implementations and all supporting components are all JavaBeans compatible. This allows Shiro to be configured with practically any configuration format such as XML (Spring, JBoss, Guice, etc), YAML, JSON, Groovy Builder markup, and more. INI is just Shiro’s ‘common denominator’ format that allows configuration in any environment in case other options are not available.
Shiro的SecurityManager实现和支持所有的JavaBean兼容。这允许Shiro可以被任意的配置格式,比如xml,YAML,JSON,Groovy Builder标记等。INI就Shiro的’公分母’格式,它允许在任何环境中配置一防其他情况(其他配置文件)不可用。
So we’ll use an INI file to configure the Shiro SecurityManager for this simple application. First, create a src/main/resources directory starting in the same directory where the pom.xml is. Then create a shiro.ini file in that new directory with the following contents:
所以这个简单的应用程序我们使用INI文件去配置Shiro SecurityManager。首先,在pom.xml开始的相同的文件夹新建一个 src/mai/resources 文件夹。之后创建一个shiro.ini文件在这个新的文件夹下并键入下面的内容到文件中:
src/main/resources/shiro.ini
# =============================================================================
# Tutorial INI configuration
#
# Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :)
# =============================================================================
# -----------------------------------------------------------------------------
# Users and their (optional) assigned roles
# username = password, role1, role2, ..., roleN
# -----------------------------------------------------------------------------
[users]
root = secret, admin
guest = guest, guest
presidentskroob = 12345, president
darkhelmet = ludicrousspeed, darklord, schwartz
lonestarr = vespa, goodguy, schwartz
# -----------------------------------------------------------------------------
# Roles with assigned permissions
# roleName = perm1, perm2, ..., permN
# -----------------------------------------------------------------------------
[roles]
admin = *
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5
As you see, this configuration basically sets up a small set of static user accounts, good enough for our first application. In later chapters, you will see how we can use more complex User data sources like relational databases, LDAP an ActiveDirectory, and more.
你看到了吗,这个配置主要创建了一组小的静态用户账户,足够满足于我们的第一个应用程序。在后续的章节,你会看到我们如何更复杂的使用User数据源就像关系型数据库、LDAP等等。
Now that we have an INI file defined, we can create the SecurityManager instance in our Tutorial application class. Change the main method to reflect the following updates:
现在我们有一个已经定义好的INI文件了,我们可以在应用程序中创建SecurityManager实例了。如下方式改变main方法:
public static void main(String[] args) {
log.info("My First Apache Shiro Application");
//1.
Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2.
SecurityManager securityManager = factory.getInstance();
//3.
SecurityUtils.setSecurityManager(securityManager);
System.exit(0);
}
And there we go - Shiro is enabled in our sample application after adding only 3 lines of code! How easy was that?
我们继续 —— 在这个简单的应用在我们添加了3行代码后就Shiro已经开启了。是不是很简单?
Feel free to run mvn compile exec:java and see that everything still runs successfully (due to Shiro’s default logging of debug or lower, you won’t see any Shiro log messages - if it starts and runs without error, then you know everything is still ok).
随变运行 mvn compile exec:java
这个命令,你会看到依然成功运行(由于Shiro默认的debug或更低的日志级别,你不会看到shiro日志信息——如果它启动运行没有错误,所有的依然是可以的。)
Here is what the above additions are doing:
这里是上面添加的内容:
We use Shiro’s IniSecurityManagerFactory implementation to ingest our shiro.ini file which is located at the root of the classpath. This implementation reflects Shiro’s support of the Factory Method Design Pattern. The classpath: prefix is an resource indicator that tells shiro where to load the ini file from (other prefixes, like url: and file: are supported as well).
我们使用Shiro的IniSecurityManager实现来读取在类路径根目录下的shiro.ini文件。这个实现反应了Shiro的工厂方法设计模式的支持。这个classpath:前缀是一个资源指示器,用来告诉shiro去哪里加载这个ini配置文件(其他的前缀,像url: 和 file: 也同样被支持)。
The factory.getInstance() method is called, which parses the INI file and returns a SecurityManager instance reflecting the configuration.
这个factory.getInstance()方法被调用,它解析了这个INI文件并且返回了一个反映这个配置的SecurityManager实例
In this simple example, we set the SecurityManager to be a static (memory) singleton, accessible across the JVM. Note however that this is not desireable if you will ever have more than one Shiro-enabled application in a single JVM. For this simple example, it is ok, but more sophisticated application environments will usually place the SecurityManager in application-specific memory (such as in a web app’s ServletContext or a Spring, Guice or JBoss DI container instance).
在这个简单的例子中,我们设置了一个静态(内存)的单例的SecurityManager跨JVM访问。但是请注意你在单个JVM中有多个应用开启了Shiro这是不可取的。这个简单的例子中这样是可以的,但是复杂的用用环境中通常会把SecurityManager放到应用特殊的内存(例如web应用的ServletContext或者一个Spring,guice或者JBoss DI容器实例中)
Now that our SecurityManager is set-up and ready-to go, now we can start doing the things we really care about - performing security operations.
现在我们的SecurityManager已经准备好了,现在我们可以开始我们真正关心的事了——执行安全操作。,
When securing our applications, probably the most relevant questions we ask ourselves are “Who is the current user?” or “Is the current user allowed to do X”? It is common to ask these questions as we’re writing code or designing user interfaces: applications are usually built based on user stories, and you want functionality represented (and secured) based on a per-user basis. So, the most natural way for us to think about security in our application is based on the current user. Shiro’s API fundamentally represents the notion of ‘the current user’ with its Subject concept.
当保护我们的应用程序时,我们可能问的最多的相关问题是『谁是当前用户』或者『当前用户被允许做X吗?』?当我们在编写代码或者设计用户接口时最常问到的问题:应用程序通常构建在用户故事上,你需要基于每个用户的基础来表示(和保护)功能。所以我们自然会想到我们应用你程序的安全是基于当前用户。Shiro API从根本上代表了"当前用户"概念和Subject概念。
In almost all environments, you can obtain the currently executing user via the following call:
在几乎所有的环境中,你可以通过下面调用获得当前正在执行的用户:
Subject currentUser = SecurityUtils.getSubject();
Using SecurityUtils.getSubject(), we can obtain the currently executing Subject. Subject is a security term that basically means “a security-specific view of the currently executing user”. It is not called a ‘User’ because the word ‘User’ is usually associated with a human being. In the security world, the term ‘Subject’ can mean a human being, but also a 3rd party process, cron job, daemon account, or anything similar. It simply means ‘the thing that is currently with the software’. For most intents and purposes though, you can think of the Subject as Shiro’s ‘User’ concept.
使用SecurityUtils.getSubject(),我们可以获得正在执行的Subject。Subject是一个安全术语,基本意思是当前正在执行的用户的安全视图。它不叫做「User」,因为「User」通过是与人类联系的。在安全里面,Subject这个术语可以代表人类,也可以是第三方程序,计划任务,守护进程,或者任何相似的东西。简单来说就是当前软件中的东西。在大多数情况下你可以把Subject看做是Shiro的「User」的概念。
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.
在一个独立应用中getSubject()方法的调用返回一个基于应用测序特定位置的用户数据的Subject。在一个服务器环境中(例如 web app),获取的Subject是基于与用户数据相关联的当前线程或者即将到来的请求。
Now that you have a Subject, what can you do with it?
现在你有一个Subject了,你可以用他做什么呢?
If you want to make things available to the user during their current session with the application, you can get their session:
在应用程序中,你想在这这个用户会话期间做一些可以做的事,你可以获取它的session:
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!
这个Session是Shiro特有的实例,它用来提供你熟悉的HttpSession但是提供了额外的好处和一个大的不同:它不需要Http环境。
If deploying inside a web application, by default the Session will be HttpSession based. But, in a non-web environment, like this simple tutorial application, 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.
如果部署在一个web应用程序里面,这个Session是基于HttpSession的。但是在一个不是web的应用的程序里,就像这个教程,Shiro会自动默认使用Enterprise Session Manager。这意味着可以不管在部署环境的那一层你都可以使用相同的API。它开启了一个应用程序全新的世界,因为任何应用程序都不需要强制使用HttpSession或者EJB有状态会话bean。现在任何客户端技术可以分享session数据。
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?
现在你可以获取一个Subject和他的Session了。那么什么才是像检查他们是否被允许去做某件事、像违反某个角色或权限一样真正有用的东西?
Well, we can only do those checks for a known 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:
当然我们做只能是对一个已知的用户做这些检查,我们上面的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.
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:
但是他们视图登录失败了呢?你可以获取所有特定的异常,这些异常会告诉你发生了什么,允许你做相应的处理和反应:
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 your own for custom conditions Shiro might not account for. See the AuthenticationException JavaDoc for more.
这里有许多不同类型的异常你可以用来检测,或者抛出你自定义的异常,但是shiro可能不能处理。可以从AuthenticationException文档获得更多。
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 your system.
安全的最佳实践是返回登录失败消息,应为你不会想要帮助一个视图破坏你系统的攻击者。
Ok, so by now, we have a logged in user. What else can we do?
现在我们有了一个登录的用户,我们能做什么呢?
Let’s say who they are:
让我们说出他是谁:
//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 also 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.
After adding in the above code examples, here is our final Tutorial class file. Feel free to edit and play with it and change the security checks (and the INI configuration) as you like:
当添加完上面的例子代码,这里是我们最终的教程类的文件。您可以随意编辑和使用它,并根据需要更改安全检查(和INI配置):
Final src/main/java/Tutorial.java
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tutorial {
private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class);
public static void main(String[] args) {
log.info("My First Apache Shiro Application");
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
// get the currently executing user:
Subject currentUser = SecurityUtils.getSubject();
// Do some stuff with a Session (no need for a web or EJB container!!!)
Session session = currentUser.getSession();
session.setAttribute("someKey", "aValue");
String value = (String) session.getAttribute("someKey");
if (value.equals("aValue")) {
log.info("Retrieved the correct value! [" + value + "]");
}
// let's login the current user so we can check against roles and permissions:
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
token.setRememberMe(true);
try {
currentUser.login(token);
} catch (UnknownAccountException uae) {
log.info("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
log.info("The account for username " + token.getPrincipal() + " is locked. " +
"Please contact your administrator to unlock it.");
}
// ... catch more exceptions here (maybe custom ones specific to your application?
catch (AuthenticationException ae) {
//unexpected condition? error?
}
}
//say who they are:
//print their identifying principal (in this case, a username):
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
//test a role:
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
//test a typed permission (not instance-level)
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.");
}
//a (very powerful) Instance Level permission:
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!");
}
//all done - log out!
currentUser.logout();
System.exit(0);
}
}
Hopefully this introduction tutorial helped you understand how to set-up Shiro in a basic application as well Shiro’s primary design concepts, the Subject and SecurityManager.
希望这个介绍帮助你理解了在一个基础的应用中怎么去建立一个Shiro应用,也包括Shiro的设计概念,Subj和SecurityManager。
But this was a fairly simple application. You might have asked yourself, “What if I don’t want to use INI user accounts and instead want to connect to a more complex user data source?”
但是这是一个非常简单的例子程序。你可能会问你自己,如果我们使用INI用户账户并且想要连接到更加复杂的用户数据源怎么办?
To answer that question requires a little deeper understanding of Shiro’s architecture and supporting configuration mechanisms. We’ll cover Shiro’s Architecture next.
回答这个问题需要对Shiro的架构和支持配置机制有更深的理解。我们会在一下章解释shiro的架构。