我对shiro的初步认识

package com.shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @since 0.9 RC2
 */
public class HelloShiro {

    private static final transient Logger log = LoggerFactory.getLogger(HelloShiro.class);

    public static void main(String[] args) {

        //创建一个最简单的方法与配置Shiro SecurityManager
        //服务器、用户、角色和权限是使用简单的INI配置。
        //我们会做,通过使用一个工厂能摄取。ini文件和
        //返回一个SecurityManager实例:

        //使用shiro。ini文件在类路径的根
        //(文件:和url前缀负载分别从文件和url):
        //1根据配置文件获取一个shiro的的工厂类
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //2在工厂类中获取shiro的安全管理器
        SecurityManager securityManager = factory.getInstance();
        //3把securityManager放入SecurityUtils中
        SecurityUtils.setSecurityManager(securityManager);
        //4使用SecurityUtils获取当前登录的用户
        Subject currentUser = SecurityUtils.getSubject();
        //5获取当前用户的会话状态 shiro内置的session
        Session session = currentUser.getSession();

        //可自行放入一些属性到session里,然后根据自己的业务逻辑进行处理
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("Retrieved the correct value! [" + value + "]");
        }
        //6判断当前用户是否已验证身份
        if (!currentUser.isAuthenticated()) {
            System.out.println("当前用户没有登录---->");
            //7模拟创建一个登录令牌
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);
            try {
                //8进行登录操作
                //登录流程
                //currentUser.login(token);--->调用了securityManager.login(this, token)方法
                //---securityManager的login方法首先调用AuthenticatingSecurityManager的authenticate(AuthenticationToken token)方法
                //---然后AuthenticatingSecurityManager的authenticate方法调用了ModularRealmAuthenticator的doAuthenticate(AuthenticationToken authenticationToken)
                //---然后ModularRealmAuthenticator的doAuthenticate方法获取配置文件的的realm,如果配置文件没有定义realm,则默认使用SimpleAccountRealm
                //--,若配置文件配置了多个realm,则遍历这些realm,并一一调用realm里的getAuthenticationInfo方法来获取AuthenticationInfo(身份验证信息)验证当前登录用户
                //---从以上流程说明,我们可以通过自定多个realm,然后覆盖getAuthenticationInfo方法,从而达到自定义验证身份的方法
                currentUser.login(token);
                //Principal因为是object类型,所以我们在实际业务中可以自己扩展这个类
                System.out.println("用户已登录---->  用户名:"+currentUser.getPrincipal().toString());
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            catch (AuthenticationException ae) {
            }
        }

        //9判断当前登录用户的角色---
        //从源代码可以看出,currentUser.hasRole("schwartz")---调用了securityManager.hasRole(getPrincipals(), roleIdentifier)的方法
        //再然后调用了AuthorizingRealm的hasRole(PrincipalCollection principal, String roleIdentifier)方法,
        //而AuthorizingRealm的hasRole方法会先使用getAvailableAuthorizationCache()在缓存里获取AuthorizationInfo,如果缓存里没有AuthorizationInfo
        //则默认的子类SimpleAccountRealm里获取的doGetAuthorizationInfo的方法里AuthorizationInfo(授权信息),而子类SimpleAccountRealm会在 factory.getInstance();时就把用户和角色放入一个map中,
        //也就是说我们可以通过自定义AuthorizingRealm然后覆盖doGetAuthorizationInfo方法来实现我们的自定义验证授权信息
        if (currentUser.hasRole("schwartz")) {
            log.info("May the Schwartz be with you!");
        } else {
            log.info("Hello, mere mortal.");
        }

        //test a typed permission (not instance-level)
        //10权限验证
        //从源代码可以看出currentUser.isPermitted("lightsaber:weild")---调用了securityManager.isPermitted(getPrincipals(), permission),
        //----然后调用了AuthorizingRealm的isPermitted(PrincipalCollection principals, String permission),该方法里获取默认的permissionResolver,就是权限字符的解析器
        //---然后调用了AuthorizingRealm。getAuthorizationInfo(),首先在缓存里获取AuthorizationInfo,如果没有,再从子类的SimpleAccountRealm的 doGetAuthorizationInfo去获取AuthorizationInfo
        //----也就是说,我们可以通过AuthorizingRealm类,然后实现doGetAuthenticationInfo方法,从而实现自己业务逻辑的权限验证
        if (currentUser.isPermitted("lightsaber:weild")) {
            log.info("You may use a lightsaber ring.  Use it wisely.");
        } else {
            log.info("Sorry, lightsaber rings are for schwartz masters only.");
        }

        //a (very powerful) Instance Level permission:
        if (currentUser.isPermitted("winnebago:drive:eagle5")) {
            log.info("You are permitted to ‘drive‘ the winnebago with license plate (id) ‘eagle5‘.  " +
                    "Here are the keys - have fun!");
        } else {
            log.info("Sorry, you aren‘t allowed to drive the ‘eagle5‘ winnebago!");
        }

        //all done - log out!
        currentUser.logout();
        System.exit(0);
    }
}
时间: 2024-10-26 17:00:00

我对shiro的初步认识的相关文章

shiro权限控制(一):shiro介绍以及整合SSM框架

shiro安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证.授权.加密和会话管理等功能 . shiro能做什么? 认证:验证用户的身份 授权:对用户执行访问控制:判断用户是否被允许做某事 会话管理:在任何环境下使用 Session API,即使没有 Web 或EJB 容器. 加密:以更简洁易用的方式使用加密功能,保护或隐藏数据防止被偷窥 Realms:聚集一个或多个用户安全数据的数据源 单点登录(SSO)功能. 为没有关联到登录的用户启用 "Remember Me&q

Apache shiro配置与使用(Spring整合)

网络上大部分的博文是关于Apache shiro与Spring MVC的整合,以及使用教程,最近在做一个物流项目的时候使用的是Apache shiro与Spring进行整合,期间遇到了一些问题,花费了一些时间才得到解决,所以本文首先会从介绍shiro框架到理解shiro以及使用shiro框架几个角度进行描述如何正确的使用与理解该框架: 1.权限概述(正确理解认证.授权的基本概念) 2.常见的权限控制的方式(URL拦截的方式.方法注解的方式) 3.权限涉及到的数据表以及模型关系 4.Apache

使用Shiro 集合Spring来实现权限控制

这只是笔记 web.xml中引入 spring-shiro.xml spring-shiro.xml : <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" x

Shiro(二):Spring-boot如何集成Shiro(上)

这篇文章主要介绍了spring-boot是如何集成shiro的authentication流程的. 从shiro-spring-boot-web-starter说起 shiro-spring-boot-web-starter是shiro在web环境下快速集成至spring-boot的配置包.其本身引入了shiro的必要模块.并在Configuration中以@Bean的形式声明了Shiro各组件,交由spring容器统一管理.先看META-INF定义了配置类: org.springframewo

Spring Boot + Shiro 实现前后端分离、权限控制

本文总结自实习中对项目的重构.原先项目采用Springboot+freemarker模版,开发过程中觉得前端逻辑写的实在恶心,后端Controller层还必须返回Freemarker模版的ModelAndView,逐渐有了前后端分离的想法,由于之前,没有接触过,主要参考的还是网上的一些博客教程等,初步完成了前后端分离,在此记录以备查阅. 一.前后端分离思想 前端从后端剥离,形成一个前端工程,前端只利用Json来和后端进行交互,后端不返回页面,只返回Json数据.前后端之间完全通过public A

shiro小记

今天主要看了shiro的认证,授权功能初步了解了一下,其他的功能用的不多,之后再看. 认证 下面的例子是以继承了AuthenticatingRealm的自定义Realm来实现自定义认证.认证依赖于方法doGetAuthenticationInfo,需要返回一个AuthenticationInfo,通常返回一个他的子类SimpleAuthenticationInfo,构造方法的第一个参数是用户名,第二个是验证密码,第三个是当前realm的className. package com.demo.re

shiro实现APP、web统一登录认证和权限管理

先说下背景,项目包含一个管理系统(web)和门户网站(web),还有一个手机APP(包括Android和IOS),三个系统共用一个后端,在后端使用shiro进行登录认证和权限控制.好的,那么问题来了web和APP都可以用shiro认证吗?两者有什么区别?如果可以,解决方案是什么?看着大家焦急的小眼神,接下来挨个解决上面的问题. web和APP可以用shiro统一登录认证吗? 可以.假如web和APP都使用密码登录的话,那没的说肯定是可以的,因为对于shiro(在此不会介绍shiro详细知识,只介

Shiro缓存(十三)

使用缓存,可以解决每次访问请求都查数据库的问题.第一次授权后存入缓存. 缓存流程 shiro中提供了对认证信息和授权信息的缓存.shiro默认是关闭认证信息缓存的,对于授权信息的缓存shiro默认开启的.主要研究授权信息缓存,因为授权的数据量大. 用户认证通过. 该 用户第一次授权:调用realm查询数据库 该 用户第二次授权:不调用realm查询数据库,直接从缓存中取出授权信息(权限标识符). -------------------------------------使用ehcache缓存框架

Spring shiro学习(一)

先转一下开涛大神的shiro基础,讲的很好 1.1  简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的Shiro就足够了.对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了. 本教程只介绍基本的Shiro使用,不会过多分析源码等,重在使用. Shiro可以非常容易的