安全框架 Shiro

Shiro

Apache Shiro 是一个强大的,容易使用的Java安全框架,用于执行身份验证,授权,密码学和会话管理。
我们另一个比较熟知的安全框架,是Spring家族中的一个Spring Security,但是两者相比来说,使用Shiro会更为简单,更为小巧,更容易上手。
贴一张Shiro官网出示的体系结构的图:
Shiro体系结构
总共包含的是六个部分,翻译成中文就是:
Shiro
而我们需要知道的,也是最为基础的,其实就是认证授权两个方面。

Shiro的核心API

也就是三个东西:

  1. Subject(这个不是很好理解)
    用户主体,简单理解就是代表当前用户的安全操作。
    Subject认证主体包含两个信息:
    1. Principals:身份,可以是用户名,邮箱,手机号等等,表示的是一个登录的主体的身份。
    2. Credentials:凭证,比如密码,数字证书等等。
  2. SecurityManager
    安全管理器,也就是管理所有用户的安全操作,通过SecurityManager来管理内部组件的实例,并提供安全管理的各种各样的服务。
  3. Realm
    Shiro连接数据的桥梁,桥梁的以便是应用安全数据,一边是Shiro。
    举个例子:当用户执行登录操作的时候,会验证用户的用户名和密码,这个时候Shiro会从应用配置的Realm中查找用户,进行验证。

三者的关系呢,就是:
Subject 去关联 SecurityManager (Subject把操作交给SecurityManager来完成);而SecurityManager 去关联 Realm。

SpringBoot 整合 Shiro

  1. 导入依赖 这里采取的是Maven管理 所以修改pom.xml文件
    PS:版本可能会有不同,需要按照实际的情况来确定!!!
    SpringBoot相关的依赖直接通过STS创建即可,这里就不张贴了。

      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.4.0</version>
    </dependency>
    
  2. 自定义Realm类 这里是需要自己编写 两个重要的东西,一个是认证,一个是授权
    定义的是如何用户如何进行认证,以及给对应的资源/用户授予权限。

    /**
    * 自定义Realm类
    * 需要继承AuthorizingRealm
    */
    public class MyRealm extends AuthorizingRealm {
      	/**
      	* 执行授权的逻辑 Authorization
      	* 可以将数据库中的角色和权限授权给用户
      	*/
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
         	//给资源进行授权
         	SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo ();
         	//添加资源的授权字符串
         	info.addStringPermission("user"); //这里的user 怎么来的呢?是在配置类中配置的,类似于页面的限制访问,这里是权限
            return simpleAuthorizationInfo;
        }
     
        /**
        * 执行认证的逻辑 Authentication
        * 可以从数据库从查询
        */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        		//例子  数据库中的用户名和密码
        		String Username = "admin";
        		String password = "123";
           		//编写shiro的认证的逻辑  判断用户名和密码
           		//1.判断用户名
           		UsernamePasswordToken token = (UsernamePasswordToken) Token;
           		if(!token.getUsername().equals(name)){
    				return null;//此时Shiro底层抛出UnKnownAccountException 
    			}
    			//判断密码 Shiro会自动的判断
                return new SimpleAuthenticationInfo("需要返回的一些数据",password,"shiro的名字");
            }
        }
    
  3. 配置Shiro配置类

    @Configuration
    public class ShiroConfig {
    	/**
    	* 创建ShiroFilterFactoryBean   这是一个过滤器的配置   过滤访问的url和资源的访问权限
    	*/
    	@Bean
        public ShiroFilterFactoryBean shiroFilter(@Autowired SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            // 必须设置 SecurityManager 安全管理器
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            // 拦截器
            /**
            * Shiro内置过滤器  可以实现权限相关的拦截器
            * 		常用的过滤器:
            * 			anon:无需认证,就可以访问
            * 			authc:必须认证,才可以访问
            * 			user:如果使用rememberMe的功能,可以直接访问 这是一个专门的过滤器
            * 			perms:必须授予资源权限才可以访问
            * 			role:资源必须得到角色权限才可以访问
            */
            Map<String, String> filterChainDefinitionMap= new LinkedHashMap<String, String>();
            filterChainDefinitionMap.put("/login", "anon");
            filterChainDefinitionMap.put("/**", "authc");
    
            // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
            shiroFilterFactoryBean.setLoginUrl("/login");
            // 登录成功后要跳转的链接
            shiroFilterFactoryBean.setSuccessUrl("/index");
            // 未授权界面;
            shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
            
            shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
            return shiroFilterFactoryBean;
        }
    	/**
    	* 创建 DefaultWebSecurityManager  也就是SecurityManager 安全管理器的配置  需要关联自己自定义的Realm
    	*/
        @Bean
        public DefaultWebSecurityManager securityManager(@Autowired MyRealm myRealm) {
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            //  对于SecurityManager 是需要关联 Realm的
            securityManager.setRealm(myRealm);
            return securityManager;
        }
    
        /**
         *  创建Realm  这里的Realm是自己定义的Realm
         */
        @Bean
        public MyRealm getRealm( ) {
            return myRealm();
        }
    }
    

认证

  1. 认证的流程
创建SecurityManager
主动提交认证
SecurityManager认证
Authenticator认证
Realm验证
  1. 认证判断 认证的操作在自定义Realm中定义,它定义了认证的实际逻辑
      //1. 构建SecurityManager 环境
      DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
      defaultSecurityManager.setRealm(simpleAccountRealm);
    
      //2. 主体提交认证请求
      SecurityUtils.setSecurityManager(defaultSecurityManager);
      Subject subject = SecurityUtils.getSubject();
      
      //3. 进行验证
      UsernamePasswordToken token = new UsernamePasswordToken("admin", "123");
      subject.login(token);
    
      //4. 结果
      System.out.println("是否认证通过:" + subject.isAuthenticated());
      subject.logout();
      System.out.println("是否认证通过:" + subject.isAuthenticated());
    

授权

  1. 授权的流程
创建SecurityManager
主动授权
SecurityManager授权
Authorizer授权
Realm获取角色权限数据
  1. 授权判断 在配置类中进行授权的过滤,在自定义Realm类中执行的授权
    		//1. 构建SecurityManager 环境
            DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
            defaultSecurityManager.setRealm(simpleAccountRealm);
    
            //2. 主体提交认证请求
            SecurityUtils.setSecurityManager(defaultSecurityManager);
            Subject subject = SecurityUtils.getSubject();
    
    		//3. 这里是登录操作
            UsernamePasswordToken token = new UsernamePasswordToken("admin", "123456");
            subject.login(token);
            System.out.println("是否认证通过:" + subject.isAuthenticated());
    
            //4. 验证是否拥有指定角色
            subject.checkRole("admin");
            subject.checkRoles("admin", "user");
    

其他的资源参考:
慕课网-Shiro
跟我学Shiro
Shiro官网
W3Cschool-Shiro

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值