Shiro学习一
shiro是什么?
-
Apache Shiro 是 Java 的一个安全(权限)框架。
-
Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。
-
Shiro 可以完成:认证、授权、加密、会话管理、与Web 集成、缓存。
shiro功能简介:
- Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
- Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用 户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户 对某个资源是否具有某个权限;
- Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有 信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
- Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
- Web Support:Web 支持,可以非常容易的集成到Web 环境;
- Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可 以提高效率;
- Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能 把权限自动传播过去;
- Testing:提供测试支持;
- Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
- Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登 录了
shiro架构:
- Subject:应用代码直接交互的对象是 Subject,也就是说 Shiro 的对外 API 核心就是 Subject。Subject 代表了当前“用户”, 这个用户不一定 是一个具体的人,与当前应用交互的任何东西都是 Subject,如网络爬虫, 机器人等;与 Subject 的所有交互都会委托给 SecurityManager; Subject 其实是一个门面,SecurityManager 才是实际的执行者; •
- SecurityManager:安全管理器;即所有与安全有关的操作都会与 SecurityManager 交互;且其管理着所有 Subject;可以看出它是 Shiro 的核心,它负责与 Shiro 的其他组件进行交互,它相当于 SpringMVC 中 DispatcherServlet 的角色 •
- Realm:Shiro 从 Realm 获取安全数据(如用户、角色、权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户 进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/ 权限进行验证用户是否能进行操作;可以把 Realm 看成 DataSource
shiro与web简单整合:
这是一个学习渐进的过程,此博文不会一下就直接用实际工作中用的东西,是慢慢来的。
项目是采用springboot+外置tomcat来搭建的,可以从我的博文(https://blog.csdn.net/qq_41921914/article/details/103191780)中找到。我们就用此项目来做与shiro的简单整合
引入shiro依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
编写配置文件
ShiroConfig:
@Configuration
public class ShiroConfig {
//引入自己的realm
@Bean
public CustomRealm customRealm() {
CustomRealm customRealm = new CustomRealm();
return customRealm;
}
//1 .配置SecurityManager
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
//配置realm
defaultSecurityManager.setRealm(customRealm());
return defaultSecurityManager;
}
//2.配置ShiroFilter.
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//设置访问url,如果不通过此页面授权会不能访问其他url,如果未授权,访问其他url会被重定向到此页面
//注意,设置这个并不是说项目一启动就访问此页面
shiroFilterFactoryBean.setLoginUrl("/login.jsp");
//未授权页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized.jsp");
//成功后访问的也面
shiroFilterFactoryBean.setSuccessUrl("/hello.jsp");
/*配置过滤链*/
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/login.jsp", "anon");
filterChainDefinitionMap.put("/view/show.jsp","anon" );
//主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
//可以自定的来调用配置在 Spring IOC 容器中 shiro bean 的生命周期方法.
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* *
* 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
* *
* 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
* * @return
*/
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
//启用 IOC 容器中使用 shiro 的注解. 但必须在配置了 LifecycleBeanPostProcessor 之后才可以使用
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
return authorizationAttributeSourceAdvisor;
}
}
CustomRealm:
public class CustomRealm implements Realm {
@Override
public String getName() {
return null;
}
@Override
public boolean supports(AuthenticationToken authenticationToken) {
return false;
}
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
return null;
}
}
webapp目录
里面的内容可先自己随便定义,主要是先体会一下。
这里我们可以把项目默认访问的页面设置为login.jsp
启动测试流程:
- 启动项目,来到login.jsp页面
- 这时我们在url中访问 hello.jsp页面,会发现我们被重定向到了login.jsp页面,这就是我们在没有通过身份认证的情况下去访问其他页面,就会被重定向到login.jsp页面。
- 这时我们在url中访问show.jsp,发现可以访问,这是因为我们在shiroFilter配置了 filterChainDefinitionMap.put("/view/show.jsp",“anon” ); anon表示可以匿名访问。
ShiroFilter
- Shiro 提供了与 Web 集成的支持,其通过一个 ShiroFilter 入口来拦截需要安全控制的URL,然后 进行相应的控制
- ShiroFilter 类似于如 Strut2/SpringMVC 这种 web 框架的前端控制器,是安全控制的入口点,其 负责读取配置(如ini 配置文件),然后判断URL 是否需要登录/权限等工作。
工作原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e2sHuV2C-1574865134149)(F:\笔记\Linux_zfc\image\1574864440172.png)]
就如我们上面在shiroFilter中配置的那样,浏览器发送访问请求,shiroFilter做一个过滤,这其中loginUrl,和filterChainDefinitions(代码中是filterChainDefinitionMap)中定义了规则。
url匹配模式
- url 模式使用 Ant 风格模式
- Ant 路径通配符支持 ?、*、,注意通配符匹配不 包括目录分隔符“/”:
- ?:匹配一个字符,如 /admin? 将匹配 /admin1,但不 匹配 /admin 或 /admin/;
- *:匹配零个或多个字符串,如 /admin 将匹配 /admin、 /admin123,但不匹配 /admin/1;
- –** :匹配路径中的零个或多个路径,如 /admin/** 将匹 配 /admin/a 或 /admin/a/b
url匹配顺序
URL 权限采取第一次匹配优先的方式,即配置的规则已经被满足了,就不会向下匹配了。
比如:
filterChainDefinitionMap.put("/view/show.jsp","anon" );
//主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证
filterChainDefinitionMap.put("/**", "authc");
我们在第一行配置的show.jsp可以匿名访问,然后第三行配置所有的请求都要认证才能访问,这时show.jsp正如我们测试的那样,不通过认证也可以访问。