zoukankan      html  css  js  c++  java
  • Apache Shiro系列三,概述 —— 10分钟入门

     一、介绍

    看完这个10分钟入门之后,你就知道如何在你的应用程序中引入和使用Shiro。以后你再在自己的应用程序中使用Shiro,也应该可以在10分钟内搞定。

     

    二、概述

    关于Shiro的废话就不多说了,详情可以看本系列第一篇博文:Apache Shiro系列一:初识 

    Apache Shiro可以做什么?

    答案是很多,但是在这里我们就不展开说了,如果对这个有兴趣,可以去看Shiro特性

     

    三、下载

    1)确保安装了1.6及其以上版本的JDK,以及3.0.3以上版本的maven

    2)Download 页面下载最新版本的”Source Code Distribution”,我们下面的例子将使用1.3.2版本;

    3)解压;

    4)进入到quickstart目录;

    $ cd shiro-root-1.3.2/samples/quickstart

    5)运行quickstart

    $ mvn compile exec:java

        在看本入门文档的过程中,可以打开源文件samples/quickstart/src/main/java/Quickstart.java,并且随意修改以测试你的想法。

     

    四、QuickStart.java

    下面我们来分解说明Quickstart.java内的源码以便你可以更好的理解。

    在任何环境下你都可以通过如下代码来获取当前登录的用户。

    Subject currentUser =SecurityUtils.getSubject();

    所谓Subject其实就是其他系统中的User,这里只是换一个说法,因为能够登录系统的不仅仅是人,还有其他系统。

    如果是在一个独立的应用程序中调用getSubject(),我们会得到一个应用程序本地登录的用户信息,如果是一个web应用,则会得到一个和当前线程或者当前的session相关的用户。

    不管怎么样,现在你得到了一个用户了,接下来可以做什么呢?

     

    如果你想要让某些数据在当前用户登录会话期间内一直有效,则可以像下面这么做:

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

    我们可以把这个Session当成是HttpSession在Shiro中的特殊实现,他和HttpSession有着相似的接口,大家用起来不会陌生。但是他还有一个额外的好处:不依赖于HTTP的上下文环境。这样你就可以在一个非web应用(比如类似于本例子的命令行程序)中使用Session了。

    如果是在一个Web应用程序中使用Session,则返回的Session是一种基于HttpSession的实现;而如果是在一个非web环境下使用,则默认使用的是Enterprise Session。不管怎么样,这意味着我们不用理会应用程序的部署环境,总是使用相同的API来操作session,带来一致的用户体验。现在,web应用和非web应用可以共享session数据了。 

    到目前为止,我们得到了一个Subject以及他的Session,现在我们用它们来做点有实际意义的事情怎么样,比如检查一下这个用户是否有权限做某件事情?

    我们可以为一个已知的用户做这些检查。我们上文中的Subject代表着当前用户,但是截至目前来说,谁是当前用户呢?在真正登录之前,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 =newUsernamePasswordToken("lonestarr","vespa");
      //this is all you have to do to support 'remember me' (no config - built in!):
      token.setRememberMe(true);
      currentUser.login(token);
    }

      就这样,简单的不能再简单了。

      但是如果登录失败了怎么办?你可以通过捕获异常来准确了解到底发生了什么错误,然后针对性的做一些处理。
     
     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 }
      你可以检测很多种不同类型的异常,或者你也可以抛出自己的异常。可以 AuthenticationException JavaDoc去了解更多。
     
    小提示:
        安全领域的最佳实践是,在发生错误的时候,只给出一些通用性的错误提示。如果提示信息太详细,可能会一不小心泄漏了一些中心信息给攻击我们的黑客了。
     
      好了,到目前为止,我们有了一个已经登录的用户,然后我们还可以做些什么呢?
      比如我们可以打印一些信息来说明我们是谁:
    //print their identifying principal (in this case, a username):
    log.info("User ["+ currentUser.getPrincipal()+"] logged in successfully.");

       我们也可以测试一下看当前用户是否拥有某个角色。

     
    if( currentUser.hasRole("schwartz")){
      log.info("May the Schwartz be with you!");
    }else{
      log.info("Hello, mere mortal.");
    }
      又或者我们可以看看他是否有权限去执行针对某种数据的某种操作。
    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.");
    }
      我们还可以做一个实例级别的权限检查——看看该用户是否有权限访问某种类型数据的某个具体实例。
    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!");
    }

      真是小菜一碟,不是吗?

      最后,如果该用户已经做完了所有的事情,他就可以退出登录了。
    currentUser.logout();//removes all identifying information and invalidates their session too.

      

      好了,如果我们要在应用程序中使用Apache Shiro,了解以上这些API也就差不都了。虽然在这些优雅的代码下面隐藏了一些复杂的实现。但是对于使用者来说,真的这样就够了。
     
      不过你可能会问你自己:“在用户登录的时候,谁来负责获取用户相关的数据呢(比如用户名、密码、角色、权限等),并且在运行时谁来真正的执行这些安全检查?”,我只能说,是你是你都是你,你要实现一种自Shiro中曾作Realm的接口,并且把它继承到Shiro的配置中。
     
      但是,如何配置Realm主要和你的运行时环境有关。比如,你可能运行的是一个独立的应用、或者而是一个web应用、或者是一个依赖于spring或者JEE容器的的应用,或者是以上几种类型的组合。对于一个10分钟入门来说,以上的这些配置都太复杂了,本节的主要目的是带你熟悉一下Shiro的API以及相关的一些概念。
     
      在你继续了解其他细节之前,你可能更想先去阅读一下 用户验证向导 和 用户授权向导,然后在继续阅读其他的文档,特别是 参考手册
     
     
     
     



  • 相关阅读:
    剑指 Offer——13. 调整数组顺序使奇数位于偶数前面
    剑指 Offer——3. 从尾到头打印链表
    剑指 Offer——2. 替换空格
    剑指 Offer——1. 二维数组中的查找
    LeetCode 905. Sort Array By Parity 按奇偶校验排列数组
    LeetCode 448. Find All Numbers Disappeared in an Array找到所有数组中消失的元素
    SSH 代码笔记
    anaconda3安装caffe
    opencv多版本安装
    人脸文章与数据库
  • 原文地址:https://www.cnblogs.com/strinkbug/p/6119887.html
Copyright © 2011-2022 走看看