sprinboot+shiro+redis(用到crazycake)实现用户权限管理demo
2019-08-09 15:41
399 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cty_com/article/details/98960799
sprinboot+shiro+redis实现用户权限管理demo
建立数据库
建立5张表,分别是用户表、角色表、权限表、用户角色表、角色权限表:
其中用户表、角色表、权限表是实体表,用户角色表、角色权限表是功能表,用于连接三张实体表。
注入依赖
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis</artifactId> <version>3.1.0</version> </dependency>
创建实体model和dao层
这里用到maven自动工具,故不细说。
但是有一点需要提到的是,其中由于用户表需要实现持久化,所以用户类需要继承Serializable这个接口,至于为什么要用到接口Serializable,参考博客:为什么要实现Serializable
写redis配置
在application.yml中配置redis相关静态变量,如下:
shiro: redis: host: 127.0.0.1:6379 timeout: 1800000
这里只写了端口与连接超时时长。
接着写一个redis的配置类:
@Configuration public class New_RedisConfig { @Value("${shiro.redis.host}") private String host; @Value("${shiro.redis.timeout}") private int timeout; // private String password; public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } }
自定义realm
public class UserRealm extends AuthorizingRealm { @Autowired private UserService userService; @Autowired private IAuthQueryService authQueryService; /** * 执行授权逻辑 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行授权逻辑"); if (principalCollection == null) { throw new AuthorizationException("PrincipalCollection method argument cannot be null."); } Object principal = getAvailablePrincipal(principalCollection); if(!(principal instanceof User)) { return null; } User curUser = (User) principal; List<Role> roleList = authQueryService.queryRolesByUser(curUser.getId()); Set<String> roles = new HashSet<>(); roleList.forEach(role -> roles.add(role.getName())); List<Perm> permList = authQueryService.queryPermsByUser(curUser.getId()); Set<String> perms = new HashSet<>(); permList.forEach(perm -> perms.add(perm.getRemark())); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setRoles(roles); info.setStringPermissions(perms); return info; } /** * 执行认证逻辑 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("执行认证逻辑"); UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken; String username = upToken.getUsername(); String password=new String(upToken.getPassword()); if (StringUtils.isEmpty(username)) { throw new AccountException("用户名不能为空"); } if (StringUtils.isEmpty(password)) { throw new AccountException("密码不能为空"); } User user = new User(); user.setUsername(username); user.setPassword(password); List<User> list = userService.list(user); if(list.size() == 0){ throw new UnknownAccountException("用户名未注册"); } if(list.size()>1){ throw new UnknownAccountException("该用户名存在多个账号"); } User user_in_database = list.get(0); if (!user_in_database.getPassword().equals(user.getPassword())){ throw new InvalidAccountException("密码错误"); } return new SimpleAuthenticationInfo(user_in_database, password, getName());//搞清楚几个参数含义 } }
这个自定义的UserRealm 必须实现AuthorizingRealm 接口,并实现doGetAuthorizationInfo(授权方法)和 doGetAuthenticationInfo(认证方法),前者是权限的管理,后者是登陆认证的管理。
另外在上面代码中,我实现的是权限动态的获取,从perm表和role表里把用户的perm和role都查出来存入info中(至于这个info是不是存入缓存中了,我一时也想不起来,以后再说)。
配置shiro
@Configuration public class ShiroConfig { @Autowired private IAuthQueryService authQueryService; /** * 1.Realm */ @Bean(name = "userRealm") public UserRealm getUserRealm(){ return new UserRealm(); } /** * 2.DefaultWebSecurityManager */ @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //关联Realm securityManager.setRealm(userRealm); securityManager.setSessionManager(sessionManager()); return securityManager; } /** * 3.ShiroFirterFactoryBean */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ System.out.println("Shiro注入成功"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //安全管理器(关联SecurityManager) shiroFilterFactoryBean.setSecurityManager(securityManager); // 获取匿名权限url List<Perm> perms = authQueryService.queryAnonPerms(); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); //开放匿名方法 if(perms != null && perms.size() > 0) { perms.forEach(perm -> { if(!StringUtils.isEmpty(perm.getPermUrl())) { filterChainDefinitionMap.put(perm.getPermUrl(), "anon"); }}); } //添加过滤器 filterChainDefinitionMap.put("/demo3/user/*","anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); Map<String, Filter> filters = shiroFilterFactoryBean.getFilters(); filters.put("authc", shiroAccessFilter()); return shiroFilterFactoryBean; } //生命周期处理器 @Bean @DependsOn("lifecycleBeanPostProcessor") public static DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); creator.setProxyTargetClass(true); return creator; } //未登录拦截 @Bean public ShiroAccessFilter shiroAccessFilter() { return new ShiroAccessFilter(); } @Bean public RedisCacheManager redisCacheManager(){ // crazycake 实现 RedisCacheManager cacheManager = new RedisCacheManager(); cacheManager.setRedisManager(redisManager()); return cacheManager; } @Bean public RedisManager redisManager(){ // crazycake 实现 New_RedisConfig redisConfig = redisConfig(); RedisManager redisManager = new RedisManager(); redisManager.setHost(redisConfig.getHost()); redisManager.setTimeout(redisConfig.getTimeout()); return redisManager; } @Bean public New_RedisConfig redisConfig(){ return new New_RedisConfig(); } @Bean public DefaultWebSecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setAuthenticator(customizedModularRealmAuthenticator()); List<Realm> realms = new ArrayList<>(); realms.add(getUserRealm()); securityManager.setRealms(realms); // 设置sessionManager securityManager.setSessionManager(sessionManager()); securityManager.setCacheManager(redisCacheManager()); // 配置缓存的话,退出登录的时候crazycake会报错,要求放在session里面的实体类必须有个id标识 return securityManager; } @Bean public CustomizedModularRealmAuthenticator customizedModularRealmAuthenticator() { CustomizedModularRealmAuthenticator authenticator = new CustomizedModularRealmAuthenticator(); authenticator.setAuthenticationStrategy(new FirstSuccessfulStrategy()); return authenticator; } @Bean public FilterRegistrationBean registration(ShiroAccessFilter filter) { FilterRegistrationBean registration = new FilterRegistrationBean(filter); registration.setEnabled(false); return registration; } @Bean public SessionManager sessionManager(){ LoginWebSessionManager sessionManager = new LoginWebSessionManager(); // 设置session超时 sessionManager.setGlobalSessionTimeout(redisConfig().getTimeout()); // 删除无效session sessionManager.setDeleteInvalidSessions(true); // 设置JSESSIONID sessionManager.setSessionIdCookie(cookie()); // 设置sessionDAO sessionManager.setSessionDAO(sessionDAO()); return sessionManager; } @Bean public SimpleCookie cookie(){ // cookie的name,对应的默认是 JSESSIONID SimpleCookie cookie = new SimpleCookie("SHAREJSESSIONID"); cookie.setHttpOnly(true); // path为 / 用于多个系统共享JSESSIONID cookie.setPath("/"); return cookie; } @Bean public RedisSessionDAO sessionDAO(){ // crazycake 实现 RedisSessionDAO sessionDAO = new RedisSessionDAO(); sessionDAO.setKeyPrefix("demo3:session:"); sessionDAO.setRedisManager(redisManager()); // Session ID 生成器 sessionDAO.setSessionIdGenerator(sessionIdGenerator()); return sessionDAO; } @Bean public JavaUuidSessionIdGenerator sessionIdGenerator(){ return new JavaUuidSessionIdGenerator(); } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } }
还有很多工具类,不一一拿出来细说,我放在上传资源中。
相关文章推荐
- springboot+shiro+mybatis+Thymeleaf实现用户权限管理
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot2.0整合Shiro框架实现用户权限管理的示例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十一):集成 Shiro 框架
- 如何在 Spring Boot 中用 Shiro 实现权限管理
- springboot 整合 shiro、JPA 、sqlserver实现权限管理
- 基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(十)【权限架构生产者(用户管理)】
- 本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例。
- spring-boot 整合 spring-security(用户管理,角色管理,权限管理,验证码,注册功能实现)
- 单体物联平台系统(Springboot整合shiro实现多realm多用户表多权限表登陆)
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- spring boot mybatis 整合shiro简单实现登陆权限管理
- spring boot配置shiro安全框架及用户登录权限验证实现
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例