shiro核心就是过滤器。
认证授权流程:
● 认证:对用户的身份进行检查(登录验证)
● 授权:对用户的权限进行检查(是否有对应的操作权限)
● 流程图:
权限管理
实现权限的动态分配,但还是不太灵活:
安全框架:
● 安全框架就是帮助我们在应用系统开发过程完成认证及授权的工作。
● 帮助我们完成用户身份认证及权限检查功能框架
● 常用的安全框架:
● shiro:Apache Shiro是一个功能强大并且易用的java安全框架(小而简单)
● spring Security:基于Spring的一个安全框架,依赖Spring。
● OAuth2:第三方授权登录(比如说王者可以微信登录和QQ)
● 自定义安全认证中心
shiro
● Apache Shiro是一个功能强大并且易用的java安全框架(小而简单)
● 可以完成用户认证,授权,密码及会话管理。
● 可以任何的应用系统中使用(主要针对单体项目的权限管理)
Shiro的工作原理:
shiro的核心功能:
● Authentication 认证,验证用户是否有相应的身份-登录认证;
● Authorization 授权,即权限验证,对已经通过认证的用户检查是否具有某个权限或者角色,从而控制是否能够进行某种操作。
● Session Managment 会话管理,用户在认证成功之后创建会话,在没有退出之前,当前用户的所有信息都会保存在这个会话中,可以是普通的javaSE应用,也可以是web应用。
● Cryptography 加密,对敏感信息进行加密处理,shiro就是提供这种加密机制的。
● 支持的特性:
● Web Support—Shiro提供了过滤器,可以通过过滤器拦截web请求来处理web应用的访问控制。
Caching 缓存支持。shiro可以缓存用户信息以及用户的角色权限信息,可以提高执行效率
Concurrency shiro支持多线程应用
Testing提供测试支持
Run As 允许一个用户以另一种身份去访问
Remeber Me 记住密码功能(但一般不会去用)
● 说明:Shiro是一个安全框架,不提供用户,权限的维护,(用户的权限管理需要我们自己去设计)
shiro核心三大组件:Subject,Security Manager ,Reaim
● Subject:表示待认证和授权的用户
● SecurityManager:它是Shiro框架的核心,Shiro就是通过Security Manager来进行内部实例的管理,并通过它来提供安全管理的各种服务。
Authenticator 认证器
Anthorizer,授权器
SessionManager,会话管理器
CacheManager,缓存管理器
● Reaim:相当于Shiro进行认证和授权的数据源,充当了Shiro与安全数据之间的‘桥梁’或者‘连接器’,也就是说,当对用户进行认证(登录)和授权(访问控制)验证时,Shiro会用应用配置的Reaim中查找用户以其权限信息。
● 工作流程图:
shiro配置
基于spring:
第一种:URL 级别粗粒度权限控制
配置 web.xml 的 shiroFilter 拦截 /*
在 spring 的 applicationContext*.xml 配置文件中配置同名 bean,配置
filterChainDefinitions 拦截控制规则
xxx.html* = anon (未登录可以访问) xxx.html* =authc (必须登录才能访问 ) xxx.html* = perms[权限] (需要特定权限才能访问) xxx.html* = roles[角色] (需要特定角色才能访问 )
第二种: 方法级别细粒度权限控制
在 spring 的 applicationContext*.xml 配置 spring aop 对 spring 管理 bean 对象开启 shiro 注解支持
@RequiresPermissions(权限) 需要特定权限才能访问
@RequiresRoles(角色) 需要特定角色才能访问
@RequiresAuthentication 需要认证才能访问
第三种:通过 shiro 自定义标签,实现页面元素显示控制
shiro:authenticated 登录后才能访问
<shiro:hasPermission name=“abc”> 需要特定权限才能访问
<shiro:hasRole name=“abc”> 需要特定角色才能访问
第四种:在程序中通过代码 判断用户是否具有指定权限( 不太常用 ,有代码侵入 )
在 Spring Boot 中整合 Shiro ,有两种不同的方案:
- 第一种就是原封不动的,将 SSM 整合 Shiro 的配置用 Java 重写一遍。
- 创建 Realm
- 接下来我们来自定义核心组件 Realm:
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
if (!“javaboy”.equals(username)) {
throw new UnknownAccountException(“账户不存在!”);
}
return new SimpleAuthenticationInfo(username, “123”, getName());
}
}
在 Realm 中实现简单的认证操作即可,不做授权,授权的具体写法和 SSM 中的 Shiro 一样,不赘述。这里的认证表示用户名必须是 javaboy ,用户密码必须是 123 ,满足这样的条件,就能登录成功!
配置 Shiro
接下来进行 Shiro 的配置:
@Configuration
public class ShiroConfig {
@Bean
MyRealm myRealm() {
return new MyRealm();
}
@Bean
SecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(myRealm());
return manager;
}
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager());
bean.setLoginUrl("/login");
bean.setSuccessUrl("/index");
bean.setUnauthorizedUrl("/unauthorizedurl");
Map<String, String> map = new LinkedHashMap<>();
map.put("/doLogin", "anon");
map.put("/**", "authc");
bean.setFilterChainDefinitionMap(map);
return bean;
}
}
在这里进行 Shiro 的配置主要配置 3 个 Bean :
首先需要提供一个 Realm 的实例。
需要配置一个 SecurityManager,在 SecurityManager 中配置 Realm。
配置一个 ShiroFilterFactoryBean ,在 ShiroFilterFactoryBean 中指定路径拦截规则等。
配置登录和测试接口。
其中,ShiroFilterFactoryBean 的配置稍微多一些,配置含义如下:
setSecurityManager 表示指定 SecurityManager。
setLoginUrl 表示指定登录页面。
setSuccessUrl 表示指定登录成功页面。
接下来的 Map 中配置了路径拦截规则,注意,要有序。
这些东西都配置完成后,接下来配置登录 Controller:
@RestController
public class LoginController {
@PostMapping("/doLogin")
public void doLogin(String username, String password) {
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username, password));
System.out.println(“登录成功!”);
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println(“登录失败!”);
}
}
@GetMapping("/hello")
public String hello() {
return “hello”;
}
@GetMapping("/login")
public String login() {
return “please login!”;
}
}
- 第二种就是使用 Shiro 官方提供的一个 Starter(死大特) 来配置,但是,这个 Starter 并没有简化多少配置。
- 创建工程,和上面的一样
创建成功后,添加 shiro-spring-boot-web-starter ,这个依赖可以代替之前的 shiro-web 和 shiro-spring 两个依赖,pom.xml 文件如下:
配置 Shiro 基本信息
接下来在 application.properties 中配置 Shiro 的基本信息:
shiro.sessionManager.sessionIdCookieEnabled=true
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
shiro.unauthorizedUrl=/unauthorizedurl
shiro.web.enabled=true
shiro.successUrl=/index
shiro.loginUrl=/login
配置解释:
第一行表示是否允许将sessionId 放到 cookie 中
第二行表示是否允许将 sessionId 放到 Url 地址拦中
第三行表示访问未获授权的页面时,默认的跳转路径
第四行表示开启 shiro
第五行表示登录成功的跳转页面
第六行表示登录页面
配置 ShiroConfig
@Configuration
public class ShiroConfig {
@Bean
MyRealm myRealm() {
return new MyRealm();
}
@Bean
DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(myRealm());
return manager;
}
@Bean
ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin", “anon”);
definition.addPathDefinition("/**", “authc”);
return definition;
}
}
这里的配置和前面的比较像,但是不再需要 ShiroFilterFactoryBean 实例了,替代它的是 ShiroFilterChainDefinition ,在这里定义 Shiro 的路径匹配规则即可。
基于javase应用-shiro的基本使用
springboot整合shrio: