shiro授权&Shiro+jsp整合Springboot -Shiro

本文详细介绍了如何使用Shiro进行授权控制,并结合SpringBoot进行项目整合。从授权概念、关键对象到授权流程,再到编程式、注解式、标签式的授权实现方式,逐一展开讲解。同时,文章涵盖了Shiro的权限字符串、Realm实现、SpringBoot项目创建、Shiro环境配置、过滤器使用、MD5与Salt的认证实现,以及Redis作为缓存的配置。最后,还讨论了验证码验证的加入,为系统的安全性提供保障。
摘要由CSDN通过智能技术生成

Shiro授权

一、授权

授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。

二、关键对象

授权可简单理解为who对what(which)进行How操作:

Who,即主体(Subject),主体需要访问系统中的资源。

What,即资源(Resource),如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型资源实例,比如商品信息为资源类型,类型为t01的商品为资源实例,编号为001的商品信息也属于资源实例。

How,权限/许可(Permission),规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作许可。

三、授权流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OKEnv9Pu-1630241787266)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210829162154359.png)]

四、授权方式

  • 基于角色的访问控制

    • RBAC基于角色的访问控制(Role-Based Access Control)是以角色为中心进行访问控制

      if(subject.hasRole("admin")){
             
         //操作什么资源
      }
      123
      
  • 基于资源的访问控制

    • RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制

      if(subject.isPermission("user:update:01")){
              //资源实例
        //对01用户进行修改
      }
      if(subject.isPermission("user:update:*")){
               //资源类型
        //对01用户进行修改
      }
      123456
      

五、权限字符串

权限字符串的规则是:资源标识符:操作:资源实例标识符,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。

例子:

  • 用户创建权限:user:create,或user:create:*
  • 用户修改实例001的权限:user:update:001
  • 用户实例001的所有权限:user : * :001
  • A:B:C,A通过B来操作C

六、shiro中授权编程实现方式

  • 编程式

    Subject subject = SecurityUtils.getSubject();
    if(subject.hasRole(“admin”)) {
         
    	//有权限
    } else {
         
    	//无权限
    }
    123456
    
  • 注解式

    @RequiresRoles("admin")
    public void hello() {
         
    	//有权限
    }
    1234
    
  • 标签式

    JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:
    <shiro:hasRole name="admin">
    	<!— 有权限—>
    </shiro:hasRole>
    注意: Thymeleaf 中使用shiro需要额外集成!
    12345
    

七、开发授权

1.realm的实现
public class CustomMD5Realm extends AuthorizingRealm {
   
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
   
        System.out.println("===================");
        //获取主身份,也就是用户名
        String primaryPrincipal = (String) principals.getPrimaryPrincipal();
        System.out.println("身份信息:"+primaryPrincipal);
        SimpleAuthorizationInfo  simpleAuthenticationInfo = new SimpleAuthorizationInfo();
        //添加角色
        simpleAuthenticationInfo.addRole("admin");

        simpleAuthenticationInfo.addStringPermission("user:update:*");
        simpleAuthenticationInfo.addStringPermission("product:*:*");
        return simpleAuthenticationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
   
        String username = (String) token.getPrincipal();//用户名
        if ("achang".equals(username)) {
   
            //数据库中存的密码
            String password = "a5adc0fc389b3236f04d1bf32e127440";//密码,123456的MD5加密
            String salt = "k2*dw";//盐
            //参数1:数据库用户名
            //参数2:数据库密码,md5+salt的密码
            //参数3:注册时的盐
            //参数4:realm名
            return new SimpleAuthenticationInfo(username,
                    password,
                    ByteSource.Util.bytes(salt),
                    this.getName());
        }
        return null;
    }
}

2.授权
public class TestAuthenticatorCustomMD5Realm {
   
    public static void main(String[] args) {
   
        DefaultSecurityManager securityManager = new DefaultSecurityManager();

        //设置自定义的MD5+盐+hash散列的Realm
        CustomMD5Realm md5Realm = new CustomMD5Realm();

        //设置自定义的realm使用hash凭证匹配器,来改变密码校验方式
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");//设置hash匹配器算法
        hashedCredentialsMatcher.setHashIterations(1024);//设置散列次数
        md5Realm.setCredentialsMatcher(hashedCredentialsMatcher);

        securityManager.setRealm(md5Realm);
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        //创建token令牌
        //用户登录使用明文密码访问
        UsernamePasswordToken token = new UsernamePasswordToken("achang", "123456");
        try {
   
            subject.login(token);//用户登录
            System.out.println("登录成功~~");
        } catch (UnknownAccountException e) {
   
            e.printStackTrace();
            System.out.println("用户名错误!!");
        }catch (IncorrectCredentialsException e){
   
            e.printStackTrace();
            System.out.println("密码错误!!!");
        }

        if(subject.isAuthenticated()){
   
            //基于角色权限管理
            boolean admin = subject.hasRole("admin");
            System.out.println(admin);

            //基于多角色权限控制,hasAllRoles只要有一个该subject不含有,就返回false
            boolean roles = subject.hasAllRoles(Arrays.asList("admin","super"));
            System.out.println(roles);

            //是否具有其中一个角色,返回布尔数组,含有就是t,不含有就是f
            boolean[] booleans = subject.hasRoles(Arrays.asList("admin","super","user"));

            // 基于权限字符串的访问控制,资源标识符:操作:资源类型
            boolean permitted = subject.isPermitted("product:create:001");
            boolean user = subject.isPermitted("user:update");
            System.out.println(permitted);
            System.out.println(user);

            //分别具有哪些权限
            boolean[] permitted1 = subject.isPermitted("product:create:001", "user:update");

            //同时具有哪些权限
            boolean permittedAll = subject.isPermittedAll("product:create:001", "user:update");
        }
    }

}

整合SpringBoot项目实战

零、整合思路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xHJzSeVC-1630241787271)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210829170548416.png)]

一、创建springboot项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wYo4go1P-1630241787275)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210829172104103.png)]

二、引入shiro依赖

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring-boot-starter</artifactId>
  <version>1.5.3</version>
</dependency>

三、配置shiro环境

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ghTCyVsR-1630241787278)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210829180133236.png)]

1.配置shiroFilterFactoryBean
@Configuration
public class ShiroConfig {
   
    
    //1、shiroFilter
	//负责拦截所有请求
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
   
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //注入安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //设置受限资源
        HashMap<String, String> map = new HashMap<>();
        map.put("/index.jsp","authc");//authc 请求这个资源,需要认证授权
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        //默认认证界面路径
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");

        return shiroFilterFactoryBean;
    }
    
    //2、安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
   
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(realm);
        return defaultWebSecurityManager;
    }
    
    //3、自定义Realm
    @Bean
    @Primary
    public Realm getRealm(){
   
        return new CustomRealm();
    }

}

3.创建自定义realm
//自定义Realm
public class CustomRealm extends AuthorizingRealm {
   
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
   
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
   
        return null;
    }
}

4.编写控制器跳转至index.html
@Controller
public class IndexController {
   
    @RequestMapping("index")
    public String index(){
   
        System.out.println("跳转至主页");
        return "index";
    }
}

在这里插入图片描述

5.启动springboot应用访问index

在这里插入图片描述

  • 注意:
    • 默认在配置好shiro环境后默认环境中没有对项目中任何资源进行权限控制,所有现在项目中所有资源都可以通过路径访问
6.加入权限控制
  • 修改ShiroFilterFactoryBean配置

    //设置受限资源
    HashMap<String, String> map = new HashMap<>();
    map.put("/index.jsp","authc");//authc 请求这个资源,需要认证授权
    //map.put("/**","authc");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
    
    //默认认证界面路径
    shiroFilterFactoryBean.setLoginUrl("/login.jsp");
    
    
    • /** 代表拦截项目中一切资源 authc 代表shiro中的一个filter的别名,详细内容看文档的shirofilter列表
7.重启项目访问查看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值