Shiro官方文档之QuickStart(Shiro入门)

Shiro

shiro官方文档:http://shiro.apache.org/10-minute-tutorial.html
shiro官方介绍:

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.

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

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.

实际上,它实现了管理你的应用程序安全的所有方面.它建立在完善的接口驱动和面向对象原则之上,为任何你能想到的用户的行为授权。但是对于一切都有合理的默认值,你可以对你应用程序安全放手(...怎么翻译才好??不用特殊配置,也有默认的配置,不会出现安全问题吧)。这是shiro努力要做的。

What can Apache Shiro do?

Shiro能做啥?

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.

很多...

1.下载Shiro

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

确保你安装了JDK1.6+、Maven 3.0.3+。

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

从下载页下载最终版源码:http://shiro.apache.org/download.html#earlySource 这个例子中,使用的是1.3.2发行版。

这里我已git的方式去下载源码:

$ git clone https://github.com/apache/shiro.git<br/>
$ cd shiro/samples/quickstart
$ mvn -v
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
省略....

如果是其他方式下载的zip,需要解压:

Unzip the source package:

解压源码包:

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

Enter the quickstart directory:

进入quickstart目录

$ cd shiro-root-1.3.2/samples/quickstart

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.

这会马上答应一些信息,好让你知道正在进行什么然后就退出。你可以随意阅读samples/quickstart/src/main/java/Quickstart.java这个下面的代码。如果你喜欢,你也可以改变这个文件再运行上面的mvn compile exec:java命令。

Quickstart.java

The Quickstart.java file referenced above contains 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.

Quickstart.java文件的代码引用了所有让你熟悉API的代码。把它分成几个大的部分慢慢讲,这样你可以很容易的理解发生了什么。

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. 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 recognized nomenclature. Ok, moving on…

使用SecurityUtils.getSubject(),我们可以获得当前正在执行的Subject。Subject只是应用程序中的用户"视图",(记录了这个用户在这个系统中详细的安全信息),我们实际上主观意识上叫他用户,但是我们坚决反对:许多应用程序现有的API已经存在他们自己的用户类、框架,所以我们不想与这些引起冲突,对于安全来说,这个术语Subject是实际上公认的术语。继续…

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程序),它获得的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!

这个会话是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 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.

如果部署在一个web应用中,默认的session就是基于HttpSession的。但是在一个没有web的环境下,就像这个简单的QuickStart,Shiro会默认自动的使用它的Enterprise Session Management。这意味着你可以在你的应用程序中使用相同的api,不管什么级别,不管什么部署环境,都是如此。它开启了一个应用程序新的世界,因为任何需要session的应用程序都不需要强制使用HttpSession或者EJB Stateful Session Beans。而且,现在(使用了Shiro后)任何客户端技术都可以分享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.
    //(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:

但是他们登录尝试失败了怎么办呢?你可以捕获到所有特别的类型的异常,他们会正确地告诉你发生了什么,并且允许你做出相应的处理和反应。

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 java文档获取更多。http://shiro.apache.org/static/1.3.2/apidocs/org/apache/shiro/authc/AuthenticationException.html

 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 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:

当然,我们可以执行最大程度的实例级别的权限检测——看用户是否有能力查看特殊类型实例的能力。

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.

这是从开发者角度来使用Apache Shiro的核心了,尽管有些非常复杂的东西使得它工作的如此优雅,但这真的就是全部了。

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.

你可能会问你自己,“谁负责人在用户登录的时候给这些用户数据,比如用户名,密码,角色,权限等等,又是谁在运行时真正执行这些安全检查呢?”,很好,都是你做的,通过实现Shiro调用的Realm并将它放到Shiro的配置中。

However, how you configure a Realm is largely dependent upon your runtime environment. For example, if you run a standalone application, or if you have a web based application, or a Spring or JEE container-based 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.

然而,你怎么配置一个Realm很大程度上依赖你使用的环境。例如,如果你运行的是一个独立的应用程序,或者你有一个基于web的应用程序,或者基于Spring或者JEE容器的应用,又或者由他们组合的应用程序。这个类型的配置超过了QuickStart的范围了,这个目的在于让你了解这个API和Shiro的概念。

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.

当你已经准备好跳到更详细的部分,你应该明确去阅读 Authentication Guide 和 Authorization Guide。之后可以移步到对应的文档,详细的参考手册,去解决其他问题。你可能也想加入我们邮件用户列表,你会发现我们有一个很棒的用户社区,可能得话人们都会帮助你…

Authentication Guide:

http://shiro.apache.org/java-authentication-guide.html
Authorization Guide:

http://shiro.apache.org/java-authorization-guide.html

参考手册:

http://shiro.apache.org/reference.html

文档:

http://shiro.apache.org/documentation.html

Thanks for following along. We hope you enjoy using Apache Shiro!
谢谢大家,使用Apache Shiro愉快!

附:

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

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;


/**
 * Simple Quickstart application showing how to use Shiro's API.
 *
 * @since 0.9 RC2
 */
public class Quickstart {

    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);


    public static void main(String[] args) {

        // The easiest way to create a Shiro SecurityManager with configured
        // realms, users, roles and permissions is to use the simple INI config.
        // We'll do that by using a factory that can ingest a .ini file and
        // return a SecurityManager instance:
        /**
         * 这是最简单的方法通过配置去创建一个Shiro SecurityManager。
         * realms, users, roles 和 permissions都是通过这个简单的ini文件配置的
         * 我们通过使用工厂方式读取配置文件并获取一个SecurityManager实例
         */
        // Use the shiro.ini file at the root of the classpath
        // 使用classpaht根目录的shiro.ini文件
        // (file: and url: prefixes load from files and urls respectively):
        // file: 和url: 这两个前缀分别从files和urls加载的
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();

        // for this simple example quickstart, make the SecurityManager
        // accessible as a JVM singleton.  Most applications wouldn't do this
        // and instead rely on their container configuration or web.xml for
        // webapps.  That is outside the scope of this simple quickstart, so
        // we'll just do the bare minimum so you can continue to get a feel
        // for things.
        /**
         * quickstart这个例子中,使用的SecurityManager是JVM单例的。许多应用程序不这样做。
         * 比如要配置web.xml等。但是不在quickstart范围内。
         * 我们只是最小限度的让你明白你在做什么。。。。。
         */
        SecurityUtils.setSecurityManager(securityManager);

        // Now that a simple Shiro environment is set up, let's see what you can do:
        // 现在一个简单的Shiro环境就已经设置好了
        // get the currently executing user:
        // 获取当前执行的用户
        Subject currentUser = SecurityUtils.getSubject();

        // Do some stuff with a Session (no need for a web or EJB container!!!)
        // 用session做一些事,不需要web或者EJB容器就能使用session
        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");
            // rememberMe功能
            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):
        // 获取当事人。。 这个例子就是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:wield")) {
            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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值