springboot 整合shiro
一、shiro是什么?
概念: Apache Shiro 是一个强大且易用的 Java 安全框架 能做什么:Shiro可以帮我们完成 :认证、授权、加密、会话管理、与 Web 集成、缓存等。 主要认识:: Subject(用户):当前的操作用户 获取当前用户Subject currentUser = SecurityUtils.getSubject() SecurityManager(安全管理器):Shiro的核心,负责与其他组件进行交互,实现 subject 委托的各种功能 Realms(数据源) :Realm会查找相关数据源,充当与安全管理间的桥梁,经过Realm找到数据源进行认证,授权等操作 Authenticator(认证器): 用于认证,从 Realm 数据源取得数据之后进行执行认证流程处理。 Authorizer(授权器):用户访问控制授权,决定用户是否拥有执行指定操作的权限。 SessionManager (会话管理器):支持会话管理 CacheManager (缓存管理器):用于缓存认证授权信息 Cryptography(加密组件):提供了加密解密的工具包
二、与springboot的整合
1.前期准备
数据库5张表:用户表 角色表 权限表 用户与角色的中间表 角色与权限的中间表 创建spring boot项目 导入所需要的依赖 相应的配置文件 shiro thymeleaf mybatis mysql等
页面准备:登录 主页面 等一些界面
2.ShiroConfiger配置类
@Configuration
public class ShiroConfiger {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
return shiroFilterFactoryBean;
}
@Bean(name = "defaultWebSecurityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
@Bean(name = "userRealm")
public UserRealm userRealm(){
return new UserRealm();
}
}
自定义realm(认证授权)
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
return null;
}
}
3.过滤(拦截)
过滤规则:anon 指定url可以匿名访问 authc 需登录 authcBasic 指定url需要http认证 logout 退出登录url user需要已登录或者记住我才能访问 roles 拥有某个角色才能进入 perms 拥有某个权限才能进入等
@Configuration
public class ShiroConfiger {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
Map<String,String> map=new HashMap<>();
map.put("/user/add","perms[/user/add]");
map.put("/user/update","perms[/user/update]");
map.put("/user/index","anon");
map.put("/user/other","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
shiroFilterFactoryBean.setLoginUrl("/user/login");
shiroFilterFactoryBean.setUnauthorizedUrl("/user/un");
return shiroFilterFactoryBean;
}
@Bean(name = "defaultWebSecurityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
@Bean(name = "userRealm")
public UserRealm userRealm(){
return new UserRealm();
}
书写相应的controller进行验证
4.认证
mapper层: public SysUser selectUser(@Param(“userName”) String userName); 查询数据库实现 通过用户名 查询到相应的对象 controller层:
@RequestMapping("/login2")
public String toLogin2(@RequestParam("username") String username, @RequestParam("password") String password, Model model, ServletRequest request){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
try {
subject.login(token);
return "index";
}catch (UnknownAccountException unknownAccountException){
model.addAttribute("msg","账号未找到");
return "login";
}catch (IncorrectCredentialsException incorrectCredentialsException){
model.addAttribute("msg","密码错误");
return "login";
}
}
自定义realm:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken) authenticationToken;
SysUser sysUser = userService.selectUser(usernamePasswordToken.getUsername());
if (sysUser==null){
return null;
}
return new SimpleAuthenticationInfo(sysUser,sysUser.getUserPassword(),"");
}
5.授权
mapper层: public List selectUrl(@Param(“userName”) String userName); 5表联查 查询出账号所对应能访问的url地址
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
Subject subject = SecurityUtils.getSubject();
SysUser principal = (SysUser) subject.getPrincipal();
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
List<String> list = userService.selectUrl(principal.getUserName());
for (int i=0;i<list.size();i++){
info.addStringPermission(list.get(i));
}
return info;
}
6.注销
controller层:调用当前用户的logout方法 Subject subject = SecurityUtils.getSubject(); subject.logout();
7.显示问题(登录 注销同时显示 无权限地址显示等)
shiro配置类:
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
页面整合:
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
登录 注销显示: controller: 将登录信息保存到session
Session session=subject.getSession();
session.setAttribute("loginUser",token);
注销调用当前对象的logout方法
页面:
<div th:if="${session.loginUser!=null}">
<a href="/user/logout">登出</a>
</div>
<div th:if="${session.loginUser==null}">
<a href="/user/login">登录</a>
</div>
不显示无权限的地址 页面:
<div shiro:hasPermission="/user/add">
<a href="/user/add">add</a>
</div>
<div shiro:hasPermission="/user/update">
<a href="/user/update">update</a>
</div>
<a href="/user/other">other</a>
8.MD5加密
Md5Hash hash = new Md5Hash(“1”,“admin”,3); 参数:需要加密的字符 加盐(一般为用户名) 迭代次数
|