zoukankan      html  css  js  c++  java
  • Shiro:初识Shiro及简单尝试

    Shiro

    一、什么是Shiro

      Apache Shiro是Java的一个安全(权限)框架

      作用:认证、授权、加密、会话管理、与web集成、缓存等

      下载地址:http://shiro.apache.org/download.html

    二、Shiro的架构

      1)subject:可以与应用交互的“用户”

      2)SecurityManager:相当于SpringMVC中的DispatcherServlet;是Spring的心脏,交互都由其控制。管理所有的subject且负责进行认证、授权、会话及缓存的管理。

      3)Authenticator:负责subject认证,是一个扩展点,可自定义实现;可以使用认证策略(Authentication Strategy)即什么情况下算用户通过了认证。

      4)Authorizer:授权器。决定是否有权限进行相应的操作。控制用户可以访问的有哪些

      5)Realm:可以有一个或者多个,可以认为是安全实体数据源,即用于获取安全实体的,可以是JDBC实现,也可以是内存实现等等,由用户提供。

      6)SessionManager:管理Session生命周期的组件。而Shiro并不仅仅可以在Webh环境,也可以用在普通的JavaSE环境

      7)CacheManager:缓存控制器,用来管理如用户、角色、权限等的缓存

      8)Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密

    三、谈谈一些关键的位置

    这里以结合springboot与mybatis的代码为例

            <!-- shiro与spring整合的依赖 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <!-- ali的数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!-- springboot的mybatis启动器 -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
        </dependencies>
    <!-- fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <!-- springboot的web组件 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    相关依赖
    package cn.zytao.taosir.user.config;
    
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    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;
    
    /**
     * Shiro的配置类
     * @author taosir
     */
    @Configuration
    public class ShiroConfig {
    
        /**
         * 创建Realm
         */
        @Bean(name="userRealm")
        public UserRealm getRealm() {
            return new UserRealm();
        }
        
        /**
         * 创建DefaultWebSecurityManager
         * @param userRealm
         */
        @Bean(name="securityManager")
        public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
            DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
            //关联realm
            securityManager.setRealm(userRealm);
            return securityManager;
        }
        
        /**
         * 创建ShiroFilterFactoryBean
         */
        @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
            //设置安全管理器
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            
            //添加Shiro内置过滤器
            /**
             * Shiro内置过滤器,可以实现权限相关的拦截器
             * 常用的过滤器:
             *     anon:无需认证(登录)可以访问
             *     authc:必须认证才可以访问
             *  user:如果使用rememberMe的功能可以直接访问
             *  perms:该资源必须得到资源权限才可以访问
             *  role:该资源必须得到角色权限才可以访问
             */    
            Map<String, String> filterMap= new LinkedHashMap<String,String>();
            
            
            //修改拦截后跳转的请求路径
            shiroFilterFactoryBean.setLoginUrl("/user/badRequest");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
            return shiroFilterFactoryBean;
        }
        
    }
    package cn.zytao.taosir.user.config;
    
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import cn.zytao.taosir.common.model.user.User;
    import cn.zytao.taosir.user.mapper.UserMapper;
    
    /**
     * 自定义的Realm程序
     * @author taosir
     */
    public class UserRealm extends AuthorizingRealm{
            
        @Autowired
        private UserMapper userMapper;
        
        /**
         * 执行授权逻辑
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
            System.out.println("开始执行Shiro的授权方法...");
            return null;
        }
    
        /**
         * 执行认证逻辑
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
            System.out.println("开始执行Shiro的认证方法...");        
            //编写Shiro判断逻辑,判断用户名和密码
            //判断用户名是否存在
            UsernamePasswordToken token=(UsernamePasswordToken)arg0;
            User user = userMapper.findByUsername(token.getUsername());
            if(user==null)
                return null;
            //判断密码是否正确
            return new SimpleAuthenticationInfo("",user.getPassword(),"");
        }
    
    }

    主要就是这两个相关类的关联,代码为我的实现,注解已经说明了相关位置写什么内容

    记得配上mybatis的配置

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/taosir-user?useUnicode=true&characterEncoding=utf8
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
    mybatis:
      type-aliases-package: cn.zytao.taosir.common.model.user
    package cn.zytao.taosir.user.service.impl;
    
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.subject.Subject;
    import org.springframework.stereotype.Service;
    
    import cn.zytao.taosir.common.exception.BadRequestException;
    import cn.zytao.taosir.user.service.UserService;
    
    @Service
    public class UserServiceImpl implements UserService{
        
        @Override
        public void checkLogin(String username,String password) {
            /**
             * 使用Shiro编写认证操作
             */
            //获取Subject
            Subject subject=SecurityUtils.getSubject();
            //封装用户数据
            UsernamePasswordToken token=new UsernamePasswordToken(username,password);
            //执行登录方法
            try {
                subject.login(token);
            } catch (UnknownAccountException e) {
                //用户名不存在
                throw new BadRequestException("该用户名不存在");
            } catch (IncorrectCredentialsException e) {
                //密码错误
                throw new BadRequestException("密码不正确");
            } catch (Exception e) {
                throw new BadRequestException("由于未知错误登录失败,请联系管理员或稍后重试");
            }
        }
    }
  • 相关阅读:
    Linux之间常用共享服务NFS
    linux共享服务Samba配置(Windows使用\访问)
    man alias
    seq awk tree 查看内核 分区 setup diff
    linux之sed用法
    linux下find(文件查找)命令的用法总结
    grep常见用法
    NTP服务及时间同步(CentOS6.x)
    我的pytest系列 -- pytest+allure+jenkins项目实践记录(1)
    软件生命周期&测试流程
  • 原文地址:https://www.cnblogs.com/it-taosir/p/9973237.html
Copyright © 2011-2022 走看看