本文主要内容:SpringBoot整合Shiro
###Shiro基本介绍
1.基本概念:Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理
2.Shiro的三大核心组件:Subject, SecurityManager和Realms
1. Subject:是一个安全术语,其基本意思是“当前的操作用户”,称之为“用户”并不准确,因为“用户”一词通常跟人相关,但是Subject也可以是第三方进程、后台帐户(Daemon Account)、定时作业(Corn Job)或其他类似事物,但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念
2. SecurityManager:是Subject的“幕后”推手,Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作,它是Shiro框架的核心
3. Realm:是Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当与像用户帐户这类安全相关数据进行交互,执行认证(登录)和授权(访问控制)时,Shiro会从应用配置的Realm中查找很多内容
3.Shiro核心流程:
###SpringBoot整合Shiro
1.导入相关坐标依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
2.编写Shiro核心配置类,但是Shiro核心配置类需要依赖我们自定义Realm类
public class UserRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//完成授权
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//拿到当前登陆的对象
Subject subject = SecurityUtils.getSubject();
User user = (User) subject.getPrincipal(); //这里就是获取到认证方法中的传递的user对象
//设置当前用户的权限
info.addPermission(user.getPerms()) //因为这个对象是认证传递过来的user,所以直接获取权限即可
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; //这里是强转从Controller中接收到的数据
User user = userService.findUserByNameAndPassword(token.getUsername(), token.getUserpassword()) //这里是从数据库中查询
if (user == null){
return null; //自动抛出异常
}
//密码Shiro会自己完成验证
return new SimpleAuthenticationInfo("user",password,"");
}
}
@RequestMapping("/login")
public String login(String username, String password, Model model){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登陆数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//执行登陆的方法
try {
subject.login(token);
return "index";
} catch (UnknownAccountException e) {
model.addAttribute("msg", "用户名错误");
return "login";
} catch (IncorrectCredentialsException e) {
model.addAttribute("msg", "密码错误");
return "login";
}
}
3.编写Shiro核心配置类
@Configuration
public class ShiroConfig {
//1. 创建realm对象
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
//2. 创建DefaultWebSecurityManager安全管理器
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//3. ShiroFilterFactoryBean的配置
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
/*
* 添加shiro的内置过滤器:
* 1. anno: 所有人都可以访问
* 2. authc: 必须认证才能访问
* 3. user:必须拥有记住我功能才能访问
* 4. perms:拥有对某个资源的权限才能访问
* 5. role:拥有某个角色权限才能访问
*/
Map<String, String> filterMap = new LinkedHashMap<>();
//也是拦截,需要授权才能登陆
filterMap.put("/user/add", "perms[user:add]"); //如果有user:add权限才能进去user下的add页面
//登陆拦截
filterMap.put("/user/*", "authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登陆的请求
bean.setLoginUrl("/toLogin"); //如果未登陆则跳转未登录页面
bean.setUnauthorizedUrl("/noauth"); //如果未授权则跳转未授权页面
return bean;
}
}