当前位置:   article > 正文

shiro的简单介绍_shrio securitymanager

shrio securitymanager

1.Shiro的简单配置

1) 获取ShiroFilterFactoryBean,作用是在执行相关操作前,先进行功能过滤,拦截所有请求,进入到shiro中进行认证与授权
例如:设置一些拦截的请求
// 身份认证失败,则跳转到登录页面的配置
bean.setLoginUrl(“/tologin”);
// 权限认证失败,则跳转到指定页面
bean.setUnauthorizedUrl(“/tologin”);

2) 创建SecurityManager,来管理shiro;Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。

3) Realm 充当了 Shiro 与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro 会从应用配置的 Realm 中查找用户及其权限信息,可见Realm的重要。
当配置 Shiro时,你必须至少指定一个 Realm ,用于认证和(或)授权。配置多个 Realm 是可以的,但是至少需要一个。

Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm,以userRealm为例子。

shiroConfig配置:

package com.example.demo.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);

       /* // 身份认证失败,则跳转到登录页面的配置
        bean.setLoginUrl("/tologin");
        // 权限认证失败,则跳转到指定页面
        bean.setUnauthorizedUrl("/tologin");*/

        //添加shiro的内置过滤器

        /**
         * anno 无需认证就可以访问必须认证了才能访问
         *authc
         * user:必须拥有记住我功能才适用
         * perms :拥有对某个资源的权限才能访问
         * role:拥有某个角色的权限
         */

        //拦截请求
//        Map<String,String> filterChainDefinitionMap =new LinkedHashMap<>();

//        filterChainDefinitionMap.put("/tologin","authc");//免登录验证

//        filterChainDefinitionMap.put("/user/update","anon");//免登录验证
//        filterChainDefinitionMap.put("/user/**","authc");//支持通配符操作  authc
//        filterChainDefinitionMap.put("/user/add","authc");//身份验证

        //方式一:anon,authc
        Map<String,String> filterChainDefinitionMap =new LinkedHashMap<>();

        filterChainDefinitionMap.put("/user/add","anon");
        filterChainDefinitionMap.put("/user/update","authc");
//        filterChainDefinitionMap.put("/**","authc");//支持通配符操作  authc
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);


       /*
       //方式二:perms
       Map<String,String> filterMap =new LinkedHashMap<>();

        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");
        bean.setFilterChainDefinitionMap(filterMap);*/


       //方式三:roles  加上roleFilter 类,并在UserRealm增加info.addRole("user");
       /*Map<String,String> filterMap =new LinkedHashMap<>();

        filterMap.put("/user/add","roles[user]");
        filterMap.put("/user/update","roles[leader]");
        bean.setFilterChainDefinitionMap(filterMap);*/



        bean.setLoginUrl("/tologin");
        //设置未授权的请求
        bean.setUnauthorizedUrl("/noauth");

        return bean;
    }

    //方式二:user

    /*
    登录接口加上  token.setRememberMe(true);

    <shiro:user>
       当有记住我信息,或已登录,则显示标签体内容
    </shiro:user>

     */

    //DefaultWebSecurityManager2
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager =new DefaultWebSecurityManager();
        //关联userRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //创建realm对象,需要自定义类1
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //整合shiroDialect:用来整合shiro thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112

userRealm配置

package com.example.demo.config;


import com.example.demo.pojo.User;
import com.example.demo.service.imp.UserServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserServiceImpl userService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了=>授权");
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();

//        info.addRole("user");

        info.addStringPermission("user:update");
        info.addStringPermission("user:add");


        //拿到当前用户登陆对象
        Subject subject= SecurityUtils.getSubject();
        User currentUser= (User) subject.getPrincipal();//拿到User对象
//        info.addStringPermission(currentUser.getPerms());//设置当前用户对象

        return info;
    }

    //认证(用户的权限)
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了=>认证");


//        String name="陈汝旭";
//        String password="123456";

        //连接真实数据库
        UsernamePasswordToken userToken =(UsernamePasswordToken) authenticationToken;
//        if (!userToken.getUsername().equals(name)){
//            return null; //抛出异常 unkonwAccountexception登录失败
//        }
//        //密码认证
//        return new SimpleAuthenticationInfo("",password,"");

        User user=userService.queryUserByName(userToken.getUsername());//获取用户名

        String name=user.getName();
        String password=user.getPwd();
        if(user==null){//说明查无此人
            return null;
        }
        return new SimpleAuthenticationInfo(user,password,name);
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

问题:“当对用户执行认证(登录)和授权(访问控制)验证时,Shiro 会从应用配置的 Realm 中查找用户及其权限信息。”,怎么实现?

2.认证的代码流程

1)执行登录的方法
subject.login(token);//执行登陆的方法
2)研究一下login()的方法,进入源码
在这里插入图片描述

3)再进入实现类
(这个login方法大多都是赋值的操作,我们可以只抓住主要的语句分析)
在这里插入图片描述
4)进入这个方法Subject subject = this.securityManager.login(this, token);的实现类
在这里插入图片描述
5)
在这里插入图片描述
6)都是一些异常处理信息,主要研究info = this.doAuthenticate(token);
在这里插入图片描述
7)这里以单realm来研究 doSingleRealmAuthentication
()

在这里插入图片描述
8)再继续下钻到了这里,主要研究 realm.getAuthenticationInfo(token);可以发现getAuthenticationInfo原来是抽象接口Realm的其中一个方法
在这里插入图片描述
9)紧接着进入realm的其中一个实现类AuthenticatingRealm
(个人觉得研究源码可以不全看懂,尽量抓住主要的语句即可,因为获取缓存中的信息无法帮助我们研究流程,可以先不理会)

在这里插入图片描述

10)doGetAuthenticationInfo一直下钻进来,可以看到我们继承的子类的方法AuthenticationInfo,然后在自定义的AuthenticationInfo进行用户认证的操作。
在这里插入图片描述
在这里插入图片描述

3.授权的代码流程

shiro判断权限的方法有subject.isPermitted(“user”),subject.hasRole(“user”);等
以subject.isPermitted(“user”)作为研究

1)点进去它的实现类DelegatingSubject,先判断身份this.hasPrincipals(),在判断授权,所以主要研究isPermitted()
在这里插入图片描述
2)再继续点进去实现类AuthorizingRealm

在这里插入图片描述
3)主要研究getAuthorizationInfo()这个方法

在这里插入图片描述
4)根据上面说的经验,缓存的方法可以先不理会,这里大多也是一些异常处理信息,所以主要研究 info = this.doGetAuthorizationInfo(principals);

在这里插入图片描述
5)再点击进去,又到了我们的老朋友userRealm的doGetAuthorizationInfo
在这里插入图片描述

正常情况这里将从数据库中获取到相对应的权限信息
(为了偷懒,这里就采用写死的方式获取权限)

在这里插入图片描述

4.三种权限认证的方式

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/534003
推荐阅读
相关标签
  

闽ICP备14008679号