了解认证授权
authentication 认证,确定用户身份,用户名密码验证
authorization 授权,对用户访问系统资源的行为做控制。常见的授权内容:后台接口访问,前台页面元素,敏感数据。
RBAC: role based access control(基于角色的访问控制)
用户,角色,权限:为角色赋予权限,为用户赋予角色
了解shiro
主要概念:认证,授权,会话管理,加密
基础API
shiro官方地址
shiro官方提供的10分钟入门教程
下载源码后:可运行shiro->sample->quickstart的demo进行体验
Shiro QuickStart
Subject currentUser = SecurityUtils.getSubject();//获取当前用户
Session session = currentUser.getSession();//获取用户缓存
currentUser.login(token);//通过抛出的异常来判断用户登录结果
currentUser.hasRole
currentUser.isPermitted
currentUser.isAuthenticated();
currentUser.logout();//退出登录
基础框架
maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
controller
MobileController
@RestController
@RequestMapping("/mobile")
public class MobileController {
@RequiresPermissions("mobile")
@RequestMapping("/query")
public String query(){
return "mobile";
}
}
SalaryController
@RestController
@RequestMapping("/salary")
public class SalaryController {
//@RequiresPermissions代替ShiroConfig中的filterMap.put("/api/salary/**", "authc,perms[salary]");配置,
//错误补充机制:通过@RequiresPermissions配置的会抛出异常,需要定义异常处理,见MyExceptionHandler
@RequiresPermissions("salary")
@RequestMapping("/query")
public String query(){
return "salary";
}
}
bean
UserBean
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserBean {
private String userName;
private String userPass;
private String userMobile;
private List<String> userRoles;
private List<String> userPerms;
}
config
ShiroConfig(shiro配置三板斧)
@Configuration
public class ShiroConfig {
//1 Realm 代表系统资源
@Bean
public Realm getRealm(){
return new MyRealm();
}
//2 SecurityManager 流程控制
@Bean
public DefaultWebSecurityManager getSecurityManager(MyRealm myRealm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(myRealm);
return defaultWebSecurityManager;
}
//3 ShiroFilterFactoryBean 请求过滤器
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager myDefaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(myDefaultWebSecurityManager);
return shiroFilterFactoryBean;
}
MyRealm
@Configuration
public class MyRealm extends AuthorizingRealm {
private Logger logger = LoggerFactory.getLogger(MyRealm.class);
@Autowired
private UserService userService;
/**
* 触发权限验证的时候才会触发该方法
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
logger.info("<<<enter MyRealm doGetAuthorizationInfo method ");
return simpleAuthorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
logger.info(">>>enter MyRealm doGetAuthenticationInfo method");
return simpleAuthenticationInfo;
}
}
基础认证功能(登录认证)
创建自己的Realm对象,继承AuthorizingRealm
实现父类的doGetAuthenticationInfo认证方法。
配置路径过滤器(MyRealm的doGetAuthenticationInfo)
//配置路径过滤器
Map<String, String> filterMap = new HashMap<>();
//key是ant路径,支持××代表多级路径,×代表单级路径,?代表单个字符, value配置shiro的默认过滤器
//shiro默认过滤器 DefaultFilter
//auth, authc, perms,roles
//表示两个资源路径需要验证
//规则判断自上而下判断,如果上下冲突,因为优先取到上面,所以越详细的规则要定义到前面来
//表示两个资源路径都需要登录才可以访问
filterMap.put("/api/mobile/**", "authc,perms[mobile]");//错误补充机制:该配置方法,没有权限就会进入下面shiroFilterFactoryBean.setUnauthorizedUrl的路径
filterMap.put("/api/salary/**", "authc,perms[salary]");
filterMap.put("/api/logout", "logout");//登出配置,如果在此写配置的话,就无需实现"/api/logout"接口
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
shiroFilterFactoryBean.setLoginUrl("/index.html");//登录页,登出或认证失败会回到登录页
shiroFilterFactoryBean.setUnauthorizadUrl("/common/unauthorized");//未授权跳转页面
基本的过滤器名称
shiro注解权限控制-5个权限注解
RequiresAuthentication:
使用该注解标注的类,实例,方法在访问或调用时,当前Subject必须在当前session中已经过认证。
RequiresGuest:
使用该注解标注的类,实例,方法在访问或调用时,当前Subject可以是“gust”身份,不需要经过认证或者在原先的session中存在记录。
RequiresPermissions:
当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。
RequiresRoles:
当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法。如果当天Subject不同时拥有所有指定角色,则方法不会执行还会抛出AuthorizationException异常。
RequiresUser
当前Subject必须是应用的用户,才能访问或调用被该注解标注的类,实例,方法。
登出,有两种方式
一.通过api接口
@GetMapping("/logout")
public void logout(){
Subject currentUser = SecurityUtils.getSubject();
currentUser.logout();
}
二.使用shiro提供的logout过滤器
filterMap.put("/api/logout", "logout"