SpringBoot+Shiro
SpringBoot+Shiro
总体来看,对Shiro的操作,是围绕Realm的对象来进行操作的,Realm提供的是待校验数据的比对值,即安全数据源
Subject currentuser = SecurityUtils.getSubject();
Session session = currentuser.getSession();
currentUser.isAuthenticated()
currentUser. getPrincipal()
currentUser.hasRo1e ("schwartz")
currentUser.isPermitted("7ightsaber:wie1d")currentUser. logout();
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.9.0</version>
</dependency>
shiro是如何工作的?
从外部来看,从应用程序的角度来观察
- Application
- Subject (the current User)
- Shiro SecurityManagrer (manager all user)
- Realm (access your security data)
- 创建一个Shiro的 Configuration 类 需要使用 @Configuration 注解
- 先创建 realm 对象,UserRealm
- 创建 DefaultWebSecurityManager 对象
- 创建 ShiroFilterFactoryBean 对象
都需要使用@Bean注册bean
- 自定义一个UserRealm类 继承AuthorizingRealm
业务一般写这里
一般创建顺序:- 重写里面的两个方法 授权和认证
- AuthorizationInfo
- AuthenticationInfo
- 登录拦截:
- SimpleAuthenticationInfo
MD5加密,MD5盐值加密:会在后面加上你的username
UserRealm相关知识点:https://blog.csdn.net/weixin_38297879/article/details/81317625
具体代码:
-
Controller
/** * @return 登录页面 */ @RequestMapping("/login") public String toLogin(String userName,String passWord, Model model, HttpSession session){ //获取当前的用户 Subject currentUser = SecurityUtils.getSubject(); //封装用户的登陆数据 放入令牌加密 UsernamePasswordToken token = new UsernamePasswordToken(userName, passWord); try { currentUser.login( token ); session.setAttribute("isLogin",userMapper.login(userName,passWord).getUserName()); } catch ( UnknownAccountException uae ) { model.addAttribute("errorMsg","用户名不存在!"); return "login"; } catch ( IncorrectCredentialsException ice ) { model.addAttribute("errorMsg","密码错误!"); return "login"; } catch ( LockedAccountException lae ) { model.addAttribute("errorMsg","账号被冻结!"); return "login"; } catch ( AuthenticationException ae ) { model.addAttribute("errorMsg","条件错误!"); } return "index"; }
-
UserRealm
public class UserRealm extends AuthorizingRealm { @Autowired private UserMapper userMapper; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行了=>授权doGetAuthorizationInfo"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // info.addStringPermission("user:add"); Subject subject = SecurityUtils.getSubject(); // 拿到当前的User对象 UserInfo currentUser = (UserInfo) subject.getPrincipal(); info.addStringPermission(currentUser.getPerms()); return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("执行了=>认证doGetAuthenticationInfo"); UsernamePasswordToken userToken = (UsernamePasswordToken) token; UserInfo user = userMapper.queryUserByName(userToken.getUsername()); if (user==null){ // UnknowAccountException return null; } //SimpleAuthenticationInfo(principal:当前认证的用户,credentials:传递的密码对象,realmName:用户名) return new SimpleAuthenticationInfo(user,user.getPassWord(),""); } }
-
ShiroConfig
@Configuration public class ShiroConfig { //3. 创建 ShiroFilterFactoryBean 对象 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); // 设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); //添加shiro的内置过滤器 /* anon: 无需认证就可以访问 authc: 必须认证才可以访问 user: 必须拥有记住我 功能才能被使用(所以一般不用) perms: 拥有对某个资源的权限才能访问 role: 拥有某个角色才能访问 */ Map<String, String> filterMap = new LinkedHashMap<>(); // 支持通配符 filterMap.put("/add","perms[user:add]"); filterMap.put("/*/*","authc"); // filterMap.put("/add","authc"); bean.setLoginUrl("/login"); bean.setUnauthorizedUrl("/unauth"); bean.setFilterChainDefinitionMap(filterMap); return bean; } //2. 创建 DefaultWebSecurityManager 对象 @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userRealm); return securityManager; } //1. 先创建 realm 对象,UserRealm @Bean(name = "userRealm") public UserRealm userRealm(){ return new UserRealm(); } //整合ShiroDialect:用来整合shiro和thymeleaf @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } }
在shiro配置文件中注入一个bean
//整合ShiroDialect:用来整合shiro和thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
<!-- shiro-thymeleaf整合-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.1.0</version>
</dependency>
在thymeleaf的html中引入命名空间:
xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro"
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a th:href="@{user/ds}">管理界面</a>
<a th:href="@{user/list}">员工列表</a>
<a shiro:guest="true" th:href="@{login}">登录</a>
<div shiro:hasPermission="user:add"><a th:href="@{add}">add</a></div>
<div shiro:hasPermission="user:update"><a th:href="@{update}">update</a></div>
</body>
</html>
- shiro:guest="true"
判断当前是否存在认证过的用户,有则不显示该内容,没有则显示 - shiro:hasPermission="user:update"
判断当前用户是拥有对应权限,有则显示,没有则不显示
本文来自博客园,作者:没有烦恼的猫猫,转载请注明原文链接:https://www.cnblogs.com/maomao777/p/16252216.html