360SDN.COM

首页/Java/列表

106.1 Spring Boot之Shiro无状态(1)

来源:SpringBoot  2017-09-11 12:22:17    评论:0点击:

【原创文章,转载请注明出处】

       问题的提出:在一些环境中,可能需要把Web应用做成无状态的,即服务器端无状态,就是说服务器端不会存储像会话这种东西,而是每次请求时带上相应的用户名进行登录。如一些REST风格的API,如果不使用OAuth2协议,就可以使用如REST+HMAC认证进行访问。HMAC(Hash-based Message Authentication Code):基于散列的消息认证码,使用一个密钥和一个消息作为输入,生成它们的消息摘要。注意该密钥只有客户端和服务端知道,其他第三方是不知道的。访问时使用该消息摘要进行传播,服务端然后对该消息摘要进行验证。

       本节博客就是要解决上面的问题,在进行正式写博客之前,我需要在此感谢一些朋友,因为这些朋友的存在,我们的QQ群才能顺利升级到了2000人。他们是:俊博、50%、似曾相识、ク方ゑ▁▂▃、蕉啊、nono、℡低头、想念!、悟空家的饭、only one、Z、J。在这里需要特别感谢下nono,其一他帮忙管理群,其二这次svip的升级也是他发起和组织的,再次对nono表示真诚的感谢,在此把这篇文章【Spring Boot之shiro无状态】献给nono。

       好了下面就进入正题,看下本节的大纲:

(1)Shiro基本知识回忆;

(2)Shiro无状态整体分析;

(3)新建Maven工程;

(4)配置pom.xml文件;

(5)编写HelloController;

(6)编写启动类App;

 

       接下来我们一起看看具体的步骤:

(1)Shiro基本知识回忆;

详情可以查看【SpringBoot Shiro权限管理】地址:http://412887952-qq-com.iteye.com/blog/2299732

       在这里我们把重要的东西先回顾下,因为在之后的讲解中我们需要用到,详情的话,看之前介绍的文章,这里不重复介绍。

       要想集成Shiro的话,我们需要知道Shiro框架的几个核心的管理对象。

第一:ShiroFilterFactory:Shiro过滤器工厂类,具体的实现类是:ShiroFilterFactoryBean,此实现类是依赖于SecurityManager安全管理器的。

第二:SecurityManager:Shiro的安全管理器,主要是身份认证的管理,缓存管理,Cookie管理,所以在时机开发中主要是和SecurityManager进行打交道的,ShiroFilterFacotory只要配置好Filter就可以了。

第三:AccessControlFilter:访问控制过滤器,对请求进行拦截处理,在这里我们可以进行一些基本的判断以及数据的基本处理,然后生成一个AuthenticationToken,然后委托给Realm进行身份的验证和权限的验证。

第四:Ream:用于身份信息权限的验证。

 

(2)Shiro无状态整体分析;

我们先看下最终要实现的结果,访问如下地址:

http://127.0.0.1:8080/hello?username=admin&params1=love&params2=girl&digest=df7f1595bd5682638556072c8ccde5edadcd807a829373d21af38fb1bc707da7

如果digest是正确的话,那么就会返回Hello,Andy,否则会login,error。

       用户访问url,进入到后台,然后会进入到我们编写的AccessControlFilter,进行访问控制过滤拦截,如果不满足条件的话,那么直接就返回了,否则接着往下处理。在AccessControlFilter中我们为委托AuthorizingRealm进行身份的认证。在AuthorizingRealm中的身份验证访问进行客户端消息摘要和服务器端消息摘要的匹配。如果成功的话,那么就会到Shiro进行进一步的处理,最后到我们的Controller,然后进行返回。经过这个流程的分析,那么我们需要以下几个对象才能完成我们的需求:

第一需要ShiroConfiguration:在这个类中主要是注入shiro的filterFactoryBean和securityManager等对象。

第二需要StatelessAccessControlFilter:这个类中实现访问控制过滤,当我们访问url的时候,这个类中的两个方法会进行拦截处理。

第三需要StatelessAuthorizingRealm:这个类中主要是身份认证,验证信息是否合理,是否有角色和权限信息。

第四需要StatelessAuthenticationToken:在shiro中有一个我们常用的UsernamePasswordToken,因为我们需要这里需要自定义一些属性值,比如:消息摘要,参数Map。

第五需要StatelessDefaultSubjectFactory:由于我们编写的是无状态的,每人情况是会创建session对象的,那么我们需要修改createSubject关闭session的创建。

第六需要HmacSHA256Utils:Java 加密解密之消息摘要算法,对我们的参数信息进行处理。

       以上就是基本这篇文章用到的几个核心的类,我们看看具体的步骤。

 

(3)新建Maven工程;

       新建一个maven工程,取名为:spring-boot-shiro-stateless

 

(4)配置pom.xml文件;

       在这里主要需要依赖于:

第一spring boot :父节点依赖;

第二shiro-spring: spring 继承shiro的依赖;

第三commons-codec:用到org.apache.commons.codec.binary.Hex;

具体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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

 

  <groupId>com.kfit</groupId>

  <artifactId>spring-boot-shiro-stateless</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <packaging>jar</packaging>

 

  <name>spring-boot-shiro-stateless</name>

  <url>http://maven.apache.org</url>

 

  <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <java.version>1.8</java.version>

  </properties>

 

 

    <!--

       spring boot 父节点依赖,

       引入这个之后相关的引入就不需要添加version配置,

       spring boot会自动选择最合适的版本进行添加。

     -->

    <parent>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-parent</artifactId>

       <version>1.4.1.RELEASE</version>

    </parent> 

   

 

 

  <dependencies>

   

    <dependency>

      <groupId>junit</groupId>

      <artifactId>junit</artifactId>

      <scope>test</scope>

    </dependency>

   

     <!-- spring boot web支持:mvc,aop...-->

    <dependency>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

   

    <!-- shiro spring. -->

    <dependency>

       <groupId>org.apache.shiro</groupId>

       <artifactId>shiro-spring</artifactId>

       <version>1.2.2</version>

    </dependency>

   

    <dependency>

            <groupId>commons-codec</groupId>

            <artifactId>commons-codec</artifactId>

      </dependency>

   

  </dependencies>

</project>

 

(5)编写HelloController;

       编写一个Rest测试类,简单测试下:

package com.kfit.controller;

 

import javax.servlet.http.HttpSession;

 

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authz.annotation.RequiresRoles;

import org.apache.shiro.session.Session;

import org.apache.shiro.subject.Subject;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

 

@RestController

public class HelloController{

   

    @RequestMapping("/hello")

   

    public String hello(String params1,String params2){

       return "hello,Andy,params1="+params1+",params2="+params2;

    }

}

 

(6)编写启动类App;

       编写Spring Boot启动类:

package com.kfit;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

 

/**

 *

 * @author Angel --守护天使

 * @version v.0.1

 * @date 2017225

 */

@SpringBootApplication

public class App {

    public static void main(String[] args) {

       SpringApplication.run(App.class, args);

    }

}

       这时候我们先启动看下效果:http://127.0.0.1:8080/hello ,正常的情况下,浏览器中会返回:

hello,Andy,params1=null,params2=null

       哈哈,说明至少到这里,我们的代码是没有问题,当然最难的部分还没开始呢,下面才是难点呢,下面部分比较复杂,单独写篇博客进行讲解。今天就先到这里吧,下篇博客见。

阅读原文

为您推荐

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权