SpringBoot整合Shiro权限管理
2020-01-15 10:58
766 查看
SpringBoot整合Shiro权限管理
Shiro(Java安全框架)1.什么是Shiro什么是权限管理
权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。
Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。
1.三个核心组件:Subject, SecurityManager 和 Realms.Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。
Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
3.用户名密码认证流程
4.授权流程
先创建一个SpringBoot项目,添加shiro的相关依赖
<!--添加 shiro 依赖--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>
修改配置文件application.yml
spring: datasource: url: jdbc:mysql://localhost:3306/project?serverTimezone=UTC username: root password: 123456 thymeleaf: cache: false encoding: utf-8 prefix: classpath:/templates/ mybatis: mapper-locations: classpath:/mapper/*.xml type-aliases-package: com.shiro.login.domain实体类
用户
@Data public class User { private String id; private String name; private String password; }
角色
@Data public class Role { private String id; private String name; }
权限
@Data public class Permission { private String id; private String name; private String url; }Mapper.xml和Service层就不贴了 ShiroConfiguration
package com.shiro.login.config; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; /** * @Author: Adorez * @Date: 2019/11/27 18:00 * @Description: */ @Configuration public class ShiroConfiguration { @Bean("userRealm") public UserRealm userRealm(){ UserRealm userRealm=new UserRealm(); return userRealm; } /** * 定义安全管理器 securityManager * @return */ @Bean("securityManager") public SecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager manager=new DefaultWebSecurityManager(); manager.setRealm(userRealm); return manager; } @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager){ ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean(); //设置securityManager bean.setSecurityManager(securityManager); //设置登录页面 bean.setLoginUrl("/login"); //设置登录成功跳转的页面 bean.setSuccessUrl("/success"); bean.setUnauthorizedUrl("/error/unAuth"); //定义过滤器 LinkedHashMap<String,String> filter=new LinkedHashMap<>(); filter.put("/","authc");//首页需要认证 filter.put("/login","anon");//登录页面无需认证 filter.put("/toLogin","anon");//登录页面无需认证 filter.put("/vip/index","roles[vip]");//添加权限配置 filter.put("/error/unAuth","authc"); //需要登录访问的资源,一般将/**放在最下边 filter.put("/**","authc"); bean.setFilterChainDefinitionMap(filter); return bean; } /** * 配置shiro和spring的关联 * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } /** * lifecycleBeanPostProcessor 是负责生命周期的 初始化和销毁的类 * @return */ @Bean("lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * Spring 的一个 bean , 由 Advisor 决定对哪些类的方法进行 AOP 代理 . * @return */ @Bean public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){ return new DefaultAdvisorAutoProxyCreator(); } /** * 页面上使用shiro标签 * @return */ @Bean(name = "shiroDialect") public ShiroDialect shiroDialect(){ return new ShiroDialect(); } }
UserRealm
package com.shiro.login.config; import com.shiro.login.domain.Permission; import com.shiro.login.domain.Role; import com.shiro.login.domain.User; import com.shiro.login.service.PermissionService; import com.shiro.login.service.RoleService; import com.shiro.login.service.UserService; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * @Author: Adorez * @Date: 2019/11/27 18:13 * @Description: */ public class UserRealm extends AuthorizingRealm { @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired private PermissionService permissionService; /** * 为用户授权 * 角色权限和对应的权限添加 * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("为用户授权"); //获取登录用户名 User userInfo = (User) principalCollection.getPrimaryPrincipal(); //查询用户名称 User user = userService.findUserByuserName(userInfo.getName()); //添加角色和权限 SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo(); //根据查询出来的用户信息获得角色 Role role = roleService.findById(Integer.valueOf(user.getId())); //添加角色1 simpleAuthorizationInfo.addRole(role.getName()); //根据查询出来的角色查询权限 List<Permission> perList = permissionService.findById(Integer.valueOf(role.getId())); for (Permission per:perList) { //添加权限 simpleAuthorizationInfo.addStringPermission(per.getName()); } return simpleAuthorizationInfo; } /** * 认证登录 * @param token * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("---认证登录"); //token携带了用户信息 UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken)token; //获取前端输入的用户名 String username = usernamePasswordToken.getUsername(); //根据用户名查询数据库中对应的记录 User user = userService.findUserByuserName(username); if (null==user) { new UnknownAccountException("账户不存在"); }else { new IncorrectCredentialsException("密码不正确"); } //当前realm对象的name String realmName = getName(); //盐值 ByteSource source=ByteSource.Util.bytes(user.getName()); /** * 封装用户信息,构建authenticationInfo对象并返回 * 参数一:用户对象 * 参数二:密码 * 参数三:盐值 * 参数四:realm的名字 */ AuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(user,user.getPassword(),source,realmName); return authenticationInfo; } }Controller
package com.shiro.login.controller; import com.shiro.login.domain.User; import com.shiro.login.service.UserService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.HttpSession; /** * @Author: Adorez * @Date: 2019/11/27 17:57 * @Description: */ @Controller public class UserController { @Autowired private UserService userService; @PostMapping("/toLogin") public String login(User user, HttpSession session){ //通过SecurityUtils.getSubject()可以获得当前的Subject Subject subject = SecurityUtils.getSubject(); //判断是否有登录信息 if(!subject.isAuthenticated()){ UsernamePasswordToken token=new UsernamePasswordToken(user.getName(),user.getPassword()); try { //执行认证操作 subject.login(token); session.setAttribute("user", subject.getPrincipal());//getPrincipal()得到当前登录的用户名 }catch (Exception e){ System.out.println(e.getStackTrace()); return "redirect:login"; } } return "redirect:/"; } @GetMapping("/logout") public String logout(){ Subject subject = SecurityUtils.getSubject(); if (subject!=null) { subject.logout(); } return "login"; } }
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <h1>用户登录</h1> <hr> <form id="from" th:action="@{/toLogin}" method="post"> <table> <tr> <td>用户名</td> <td> <input type="text" name="name" placeholder="请输入账户名"/> </td> </tr> <tr> <td>密码</td> <td> <input type="password" name="password" placeholder="请输入密码"/> </td> </tr> <tr> <td colspan="2"> <font color="red">[[${msg}]]</font> </td> </tr> <tr> <td colspan="2"> <input type="submit" value="登录"/> <input type="reset" value="重置"/> </td> </tr> </table> </form> </body> </html>
index.html
<!DOCTYPE html> <html xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <head> <title>首页</title> </head> <body> <h1>首页</h1> <hr> <ul> <li><a href="/user/index">个人中心</a></li> <shiro:hasRole name="vip"><li><a href="/vip/index">会员中心</a></li></shiro:hasRole> <li><a href="/test/index">hei</a></li> <li><a href="logout">退出登录</a></li> </ul> </body> </html>
error/unAuth.html
<!DOCTYPE html> <html> <head> <title>未授权提示</title> </head> <body> <h1>您还不是<font color="red">会员</font>,没有权限访问这个页面!</h1> </body> </html>
shiro标签的使用
guest标签 | 验证当前用户是否为“访客”,即未认证(包含未记住)的用户 |
---|---|
user标签 | 认证通过或已记住的用户 |
authenticated标签 | 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在 |
notAuthenticated | 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户 |
principal | 输出当前用户信息,通常为登录帐号信息 |
hasRole | 验证当前用户是否属于该角色 |
lacksRole | 与hasRole标签逻辑相反,当用户不属于该角色时验证通过 |
hasAnyRole | 验证当前用户是否属于以下任意一个角色 |
hasPermission | 验证当前用户是否拥有指定权限 |
lacksPermission | 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过 |
项目具体实现
链接:https://pan.baidu.com/s/1RKzOZFU81XgJJ2di7nFpCA
提取码:qzp4
- 点赞 2
- 收藏
- 分享
- 文章举报
相关文章推荐
- springboot(十四):springboot整合shiro-登录认证和权限管理
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- springboot整合shiro-登录认证和权限管理
- Spring Boot Shiro权限管理--自定义 FormAuthenticationFilter验证码整合
- Spring Boot入门教程(7)---整合jpa,Shiro进行权限管理(附源码)
- spring boot mybatis 整合shiro简单实现登陆权限管理
- spring-boot(八) springboot整合shiro-登录认证和权限管理
- springboot 整合 shiro、JPA 、sqlserver实现权限管理
- springboot(十四):springboot整合shiro-登录认证和权限管理
- springboot(十四):springboot整合shiro-登录认证和权限管理
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)
- springboot整合shiro-登录认证和权限管理
- springboot 整合shiro + cas 实现单点登录权限管理(一)(sso)
- Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理
- 转载:Spring Boot (十四):springboot整合shiro-登录认证和权限管理
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot与Shiro整合-权限管理视频教程
- springboot(十四):springboot整合shiro-登录认证和权限管理
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- springboot整合shiro-登录认证和权限管理