Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。
shiro主要包括三大核心组件:Subject、SecurityManager、Realm,其中
subject:即操作主体,封装了一系列安全操作;
SecurityManager:Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm:相当于一个DAO,提供验证所需的数据
Shiro创建流程:
1、创建Realm类继承AuthorizingRealm,重写doGetAuthorizationInfo(PrincipalCollection principalCollection)(权限验证)、doGetAuthenticationInfo(AuthenticationToken authenticationToken)(身份验证),分别返回一个
2、创建Realm配置类@Configuration加入容器中:
声明realm bean;
声明SecurityManager bean,使用默认的即可,引用realm形参;
配置shiro配置工厂shiroFilterFactoryBean(),新建shiroFactory并传入securityManager,同时配置地址与权限的map:shiroFilterFactory.setFilterChainDefinitionMap(filterMap);
开启shiro注解支持,新建AuthorizationAttributeSourceAdvisor,设置securityManager并返回。
在使用的过程中,一般是分为身份验证和权限验证两步,身份验证用Authorization,权限验证使用Authentication,其中第一个主要使用在登陆验证上,这个比较重要,因为最初始的数据就是从这一步创建的,之后的权限也涉及到一部分的数据,下面讲讲关于登陆令牌验证的事
1、先将传入的账号密码包装成UsernamePasswordToken即接口AuthenticationToken的实现类
2、利用SecurityUtil工具类创建Subject(具体上面有讲述)
3、subject.login(token),这一步进入登陆验证;
首先判断线程上下文ThreadContext有没有当前实例,如果没有的话:
进入到doGetAuthenticationInfo(AuthenticationToken authenticationToken),进行身份验证操作,在这一步可以自行访问数据库,最后返回一个SimpleAuthenticationInfo(user, user.getPassword(), this.getName())
4、在这一阶段完成之后会判断会在调用该函数的顶层函数判断是否为null的。
有趣的是,在断点调试了两次之后,感觉那个权限验证采用的是懒加载的方式。