springboot整合Shiro

shiro权限控制架构

shiro实现的认证

1、从类的继承关系可以看出自定义的Realm只需要实现AuthorizingRealm类即可。

Realm继承关系.png

2、只需要实现下列两个方法即可
doGetAuthorizationInfo 授权
doGetAuthenticationInfo 认证

shiro中的加密

  1. md5加密一般用来加密和做校验和

    • MD5算法不可逆,内容相同无论执行多少次MD5加密生成的结果始终一致。
      例如:可以对文件进行文件加密,保证文件的内容不被篡改
    • 网上常见的MD5解密,只是做了把简单的字符串进行穷举解密
    • MD5加密完始终是一个16进制的32位长度字符串

Shiro中如何使用MD5加密认证

  1. 用户登录时的处理在Realm中添加秘钥认证器
//给安全管理器设置realm
     CustomerMd5Realm customerMd5Realm=new CustomerMd5Realm();
     //自定义MD5秘钥匹配器
     HashedCredentialsMatcher hashedCredentialsMatcher=new HashedCredentialsMatcher();
     hashedCredentialsMatcher.setHashAlgorithmName("md5");//设置使用什么方式进行加密
     hashedCredentialsMatcher.setHashIterations(1024);//设置散列的次数
     customerMd5Realm.setCredentialsMatcher(hashedCredentialsMatcher);
  1. 在Realm中进行进行处理
    //ByteSource.Util.bytes("12121")是做加盐处理
     @Override
       protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
           String principal=(String)authenticationToken.getPrincipal();
           if("user".equals(principal)){
               return new SimpleAuthenticationInfo(principal,"3aa17c6555fb36a1e20783b8cdacbd8e", ByteSource.Util.bytes("12121"),this.getName());
           }
           return null;
       }
    
    

Shiro中实现授权

  1. 授权的概念

    • 授权,即访问控制,控制谁能访问哪些资源,主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是没有权限访问的
    • 授权可以简单的理解为Who对What进行How操作
      • who:即主体Subject 主体需要访问系统中的资源。
      • what:即资源Resource,如系统菜单、页面、按钮、类方法等信息。资源包括资源类型和资源实例。
      • how:授权/许可,规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限等,通过权限
        可知主体对哪些资源有哪些操作许可
  2. 授权的方式

    • 基于角色的访问控制

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

        if(subject.hasRole("admin")){
            //操作什么资源
        }
        
 - 基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制。

   ```java
   if(subject.isPermission("user:*:create")){
       
   }
   ```
  1. 权限字符串
    • 权限字符串的规则:资源标识符:操作:资源实例标识符,意思是对哪个资源的哪个实例具有什么操作,权限字符串也可以使用*通配符。
      • 用户修改权限:user:create,或者user:create:*
      • 用户修改实例001的权限:user:update:001
      • 用户实例001的所有权限:user:*:001

shiro中授权编程的方式

  • 编程方式

    if(subject.hasRole("admin")){
        
    }
    
  • 注解方式

    @RequiresRoles("admin")
    public void hello(){}
    
  • 标签方式

    jsp/GSP 标签在jsp页面通过相应的标签方式完成
    
    
    
    

开发授权

  1. realm中实现

shiro与springboot进行整合

实现的方式

springboot整合shiro需要通过Filter的方式对Url进行拦截处理

实现过程

pom文件引入包

 
        
            org.apache.shiro
            shiro-spring-boot-starter
            1.5.3
        
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
            mysql
            mysql-connector-java
        
        
            com.alibaba
            druid
            1.1.19
        

定义配置类ShiroConfig

在配置类中主要配置shiro的拦截器、shiro安全管理器、shiro访问数据库域、MD5加密

  • 配置拦截器
 /**
     * 定义拦截器
     * @param defaultWebSecurityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //给filter设置公共安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //配置访问权限
        HashMap map = new HashMap<>();
        map.put("/user/login","anon");
        map.put("/user/register","anon");
        map.put("/user/logout","anon");
        map.put("/register.jsp","anon");
        map.put("/**","authc");
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
  • 注入安全管理器
//创建安全管理器
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(AuthorizingRealm realm){
    DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
    realm.setCredentialsMatcher(getCredentialsMatcher());
    defaultWebSecurityManager.setRealm(realm);
    return  defaultWebSecurityManager;
}
  • 创建自己的访问数据库域
public class CustomRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username=(String)principalCollection.getPrimaryPrincipal();
        if("liuxiaobin".equals(username)){
            SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
            simpleAuthorizationInfo.addRole("product");
            simpleAuthorizationInfo.addRole("log");
            return simpleAuthorizationInfo;
        }
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username=(String)authenticationToken.getPrincipal();
        UserServiceImpl userService=(UserServiceImpl) SpringUtils.getBean("userService");
        User user=userService.getUserByUsername(username);
        SimpleAuthenticationInfo simpleAuthenticationInfo=null;
        if(user!=null) {
            simpleAuthenticationInfo= new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()),this.getName());
        }
        return simpleAuthenticationInfo;
    }
}
  • 注入MD5加密加盐和散列处理
  @Bean
  public CredentialsMatcher getCredentialsMatcher(){
      //自定义MD5秘钥匹配器
      HashedCredentialsMatcher hashedCredentialsMatcher=new HashedCredentialsMatcher();
      hashedCredentialsMatcher.setHashAlgorithmName("md5");//设置使用什么方式进行加密
      hashedCredentialsMatcher.setHashIterations(1024);//设置散列的次数
      return  hashedCredentialsMatcher;
  }
  • 其他额外配置

    • 盐生成类

       public static String getSalt(int n){
              char[] charts="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@@##!^%%$%$%$%$%$%$%$%$%@#(**&&&".toCharArray();
              StringBuilder sb=new StringBuilder();
              for (int i = 0; i < n; i++) {
                  char aChar=charts[new Random().nextInt(charts.length)];
                  sb.append(aChar);
              }
              return sb.toString();
          }
      
    • 获取Bean的工具类

      @Component
      public class SpringUtils implements ApplicationContextAware {
      
          private static ApplicationContext context;
      
          @Override
          public void setApplicationContext(org.springframework.context.ApplicationContext applicationContext) throws BeansException {
              this.context=applicationContext;
          }
      
          public static Object getBean(String beanName){
              
              return context.getBean(beanName);
          }
      }
      
     

## shiro 缓存

#### shiro整合ehcache

- 添加ehche依赖

```xml


    org.apache.shiro
    shiro-ehcache
    1.5.3

  • 配置realm中开启缓存

    @Bean
    public AuthorizingRealm getAuthorizingRealm(){
        CustomRealm customRealm = new CustomRealm();
        customRealm.setCredentialsMatcher(redentialsMatcher());//设置认证秘钥md5+salt+散列
        //开启缓存
        customRealm.setCachingEnabled(true);//开启全局缓存
        customRealm.setCacheManager(ehCacheManager());
        customRealm.setAuthenticationCachingEnabled(true);//开启认证缓存
        customRealm.setAuthenticationCacheName("AuthenticationCache");//设置认证缓存的名字
        customRealm.setAuthorizationCachingEnabled(true);//开启授权缓存
        customRealm.setAuthorizationCacheName("AuthorizationCache");//设置授权缓存的名字
        customRealm.setCacheManager(new EhCacheManager());//设置缓存管理器
    
        return customRealm;
    }
    

shiro整合redis

  • 添加redis依赖

      
      
          org.springframework.boot
          spring-boot-starter-data-redis
      
    
  • redis实现shiro中的CacheManager

    package com.bidr.springbootshiro.shiro.cache;
    import org.apache.shiro.cache.Cache;
    import org.apache.shiro.cache.CacheException;
    import org.apache.shiro.cache.CacheManager;
    import org.springframework.data.redis.core.RedisTemplate;
    public class RedisCacheShiroManager implements CacheManager {
        private RedisTemplate redisTemplate;
        public RedisCacheShiroManager(RedisTemplate redisTemplate){
            this.redisTemplate=redisTemplate;
        }
        @Override
        public  Cache getCache(String s) throws CacheException {
            return new ReidsCacheShiro(s,redisTemplate);
        }
    }
    
  • 设置redis的缓存

    package com.bidr.springbootshiro.shiro.cache;
    import org.apache.shiro.cache.Cache;
    import org.apache.shiro.cache.CacheException;
    import org.springframework.data.redis.core.RedisTemplate;
    import java.util.Collection;
    import java.util.Set;
    public class ReidsCacheShiro implements Cache {
    
        private RedisTemplate redisTemplate;
        private String name;
        public ReidsCacheShiro(String name,RedisTemplate redisTemplate) {
            this.redisTemplate = redisTemplate;
            this.name=name;
        }
    
    
        @Override
        public V get(K k) throws CacheException {
            System.out.println((V)redisTemplate.opsForValue().get(k.toString()));
            return (V)redisTemplate.opsForValue().get(k.toString());
        }
    
        @Override
        public V put(K k, V v) throws CacheException {
            redisTemplate.opsForValue().set(k.toString(),v);
            return v;
        }
    
        @Override
        public V remove(K k) throws CacheException {
            return null;
        }
    
        @Override
        public void clear() throws CacheException {
    
        }
    
        @Override
        public int size() {
            return 0;
        }
    
        @Override
        public Set keys() {
            return null;
        }
    
        @Override
        public Collection values() {
            return null;
        }
    }
    
    
  • shiroConfig中设置redisCacheManager

      @Bean
      public CacheManager redisCacheManager(){
          return new RedisCacheShiroManager(redisTemplate);
      }
      /**
      * 自定义realm实现
      * 1、设置MD5加密验证机制
      * 2、开启realm缓存
      * @return
      */
      @Bean
      public AuthorizingRealm getAuthorizingRealm(){
          CustomRealm customRealm = new CustomRealm();
          customRealm.setCredentialsMatcher(redentialsMatcher());//设置认证秘钥md5+salt+散列
          //开启缓存
          customRealm.setCachingEnabled(true);//开启全局缓存
          //customRealm.setCacheManager(ehCacheManager());
          customRealm.setCacheManager(redisCacheManager());
          customRealm.setAuthenticationCachingEnabled(true);//开启认证缓存
          customRealm.setAuthenticationCacheName("AuthenticationCache");//设置认证缓存的名字
          customRealm.setAuthorizationCachingEnabled(true);//开启授权缓存
          customRealm.setAuthorizationCacheName("AuthorizationCache");//设置授权缓存的名字
          customRealm.setCacheManager(new EhCacheManager());//设置缓存管理器
            return customRealm;
      }
    

shiro 集成验证码

你可能感兴趣的:(springboot整合Shiro)