SpringBoot项目Shiro的实现(二)

在看此小节前,您可能需要先看:http://www.cnblogs.com/conswin/p/7478557.html

紧接上一篇,在上一篇我们简单实现了一个Springboot的小程序,但我们发现随便访问那个页面,都无需登录即可访问,我们希望在没有登录的情况下,需要跳转到login页面进行登录后才能访问,这个时候Shiro就要闪亮登场了。

四、集成Shiro,进行用户授权。

  集成Shiro可分为如下几个步骤:

  1、pom.xml中添加Shiro依赖

  2、注入ShiroFilterFactory和SecurityManage

  3、身份认证

  4、权限控制  

  接下来逐一进行实现。

  1、pom.xml中添加Shiro依赖

       <!-- shiro spring. -->  
       <dependency>  
           <groupId>org.apache.shiro</groupId>  
           <artifactId>shiro-spring</artifactId>  
           <version>1.2.2</version>  
       </dependency>  

  2、注入ShiroFilterFactory和SecurityManage

    我们在上一节说过,Shiro几个核心的类,第一就是ShiroFilterFactory,第二就是SecurityManager,那么最简单的配置就是注入这两个类就ok了,那么如何注入呢?看如下代码:

package com.kfit.config.shiro;
 
import java.util.LinkedHashMap;
import java.util.Map;
 
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
/**
 * Shiro 配置
 *
Apache Shiro 核心通过 Filter 来实现,就好像SpringMvc 通过DispachServlet 来主控制一样。
既然是使用 Filter 一般也就能猜到,是通过URL规则来进行过滤和权限校验,所以我们需要定义一系列关于URL的规则和访问权限。
 *
 * @author Angel(QQ:412887952)
 * @version v.0.1
 */
@Configuration
public class ShiroConfiguration {
      
   
    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
     * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
     *
        Filter Chain定义说明
       1、一个URL可以配置多个Filter,使用逗号分隔
       2、当设置多个过滤器时,全部验证通过,才视为通过
       3、部分过滤器可指定参数,如perms,roles
     *
     */
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
       System.out.println("ShiroConfiguration.shirFilter()");
       ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();
      
        // 必须设置 SecurityManager 
       shiroFilterFactoryBean.setSecurityManager(securityManager);
      
      
      
       //拦截器.
       Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
      
       //配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
       filterChainDefinitionMap.put("/logout", "logout");

       //防止登录成功之后下载favicon.ico
       filterChainDefinitionMap.put("/favicon.ico", "anon");  
       filterChainDefinitionMap.put("/static/**", "anon");  
      
       //<!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
       filterChainDefinitionMap.put("/**", "authc");
      
       // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
      
       shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
       returnshiroFilterFactoryBean;
    }
   
    @Bean
    public SecurityManager securityManager(){
       DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
       return securityManager;
    }

}

  这里说下:ShiroFilterFactory中已经由Shiro官方实现的过滤器:

   Shiro内置的FilterChain

Filter Name

Class

anon

org.apache.shiro.web.filter.authc.AnonymousFilter

authc

org.apache.shiro.web.filter.authc.FormAuthenticationFilter

authcBasic

org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

perms

org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter

port

org.apache.shiro.web.filter.authz.PortFilter

rest

org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

roles

org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

ssl

org.apache.shiro.web.filter.authz.SslFilter

user

org.apache.shiro.web.filter.authc.UserFilter

  anon:所有url都都可以匿名访问;

  authc: 需要认证才能进行访问;

  user:配置记住我或认证通过可以访问;

  这几个是我们会用到的,在这里说明下,其它的请自行查询文档进行学习。

  这时候我们运行程序,访问/index页面我们会发现自动跳转到了login页面,当然这个时候输入账号和密码是无法进行访问的。下面这才是重点:任何身份认证,如何权限控制。

  3、身份验证

     在认证、授权内部实现中都有提到,最终的处理都是交由Realm进行处理的,因为在Shiro中最终是通过Realm来获取应用程序的用户、角色以及权限信息的。Realm是专用于安全框架的DAO。

     认证实现:

        Shiro的认证最终由Realm执行,这时会调用Realm的Authentication(token)方法,此方法主要执行以下操作:

        ①、检查提交的令牌token信息

        ②、根据令牌信息从数据库中获取用户信息

        ③、对用户信息进行匹配验证

        ④、验证通过将返回一个封装了用户信息的AuthenticationInfo实例

        ⑤、验证失败则抛出AuthenticationException异常

    而我们程序要做的就是自定义一个Realm类,继承AuthorizingRealm抽象类,重载doAuthenticationInfo()方法,重新获取用户信息的方法。

    既然要进行身份权限控制,少不了创建以下相关表了:

    第一、用户信息表:在用户表中保存了用户的基本信息,账号、密码、姓名,性别等。

    第二、权限表(资源+控制权限):这个表中主要是保存了用户的URL地址,权限信息

    第三、角色表:在这个表重要保存了系统存在的角色

    第四、角色-权限关联表(每个角色都有什么权限可以进行操作)

    

原文地址:https://www.cnblogs.com/conswin/p/7478922.html