我是靠谱客的博主 辛勤毛巾,这篇文章主要介绍SpringBoot整合shiro同时解决注解权限不生效(附源码)1.数据库表设计2.实体:3.查询当前登陆用户方法,获取所有角色,所有权限4.pom配置5.shiroConfig配置6.配置自己的  realm7.方法上加权限8,运行效果9.源码地址:,现在分享给大家,希望可以做个参考。

1.shiro apache出品的很好用的权限框架,理论上来说只需要程序员配置两个类,shiro就能为我们工作起来。

这几天研究shiro,集成到springboot中,并使用注解权限,踩了不少坑,希望这篇文章能够帮助到大家

本文我将讲述一下springboot整合shiro,使用 @RequiresPermissions 进行控制器权限控制

1.数据库表设计

具体sql文件以及初始化数据在这里:https://github.com/winterme/pkusoft/blob/master/src/sql/user_center.sql

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `uid` varchar(36) NOT NULL, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `password_salt` varchar(255) DEFAULT NULL, `status` varchar(255) DEFAULT NULL, `create_user` varchar(255) DEFAULT NULL, `create_uid` varchar(36) DEFAULT NULL, `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `sys_role_permission`; CREATE TABLE `sys_role_permission` ( `rid` varchar(36) DEFAULT NULL, `pid` varchar(36) DEFAULT NULL, `role_name` varchar(255) DEFAULT NULL, `create_user` varchar(255) DEFAULT NULL, `create_uid` varchar(36) DEFAULT NULL, `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `sys_user_role`; CREATE TABLE `sys_user_role` ( `id` varchar(36) NOT NULL, `uid` varchar(36) NOT NULL, `rid` varchar(36) NOT NULL, `create_user` varchar(255) DEFAULT NULL, `create_uid` varchar(36) DEFAULT NULL, `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `sys_permission`; CREATE TABLE `sys_permission` ( `pid` varchar(36) NOT NULL, `permission_name` varchar(255) DEFAULT NULL, `permission` varchar(255) DEFAULT NULL, `url` varchar(255) DEFAULT NULL, `create_user` varchar(255) DEFAULT NULL, `create_uid` varchar(36) DEFAULT NULL, `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`pid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.实体:

在user里面放入 roles和permisssion 两个属性,用来查询user 的时候手动关联查出 该用户的角色和权限

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Table(name = "sys_user") public class SysUser { @Id private String uid; private String username; private String password; @Column(name = "password_salt") private String passwordSalt; // 所有的角色 private List<String> roles; // 所有的权限 private List<String> permission; private String status; @Column(name = "create_user") private String createUser; @Column(name = "create_uid") private String createUid; @Column(name = "create_time") private Date createTime; .....getset

3.查询当前登陆用户方法,获取所有角色,所有权限

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Override public SysUser getUserByUserNameWithPermission(String username) { // 用户名唯一,此处用用户名查出当前用户 Example example = new Example(SysUser.class); Example.Criteria criteria = example.createCriteria(); criteria.andEqualTo("username",username); List<SysUser> lists = sysUserMapper.selectByExample(example); if( lists.size()==0 ){ return null; } SysUser sysUser = lists.get(0); // 查出所有的角色名 List<SysRolePermission> roles = sysRolePermissionMapper.getRoleNameByUserId(sysUser.getUid()); // 查出所有的权限 List<SysPermission> permissions = sysPermissionMapper.getSysPermissionByUid(sysUser.getUid()); // roleName List<String> rolesName = new ArrayList<>(); for (SysRolePermission role : roles ) { rolesName.add( role.getRoleName() ); } sysUser.setRoles( rolesName ); // permissions List<String> permissionsByUser = new ArrayList<>(); for (SysPermission p : permissions) { permissionsByUser.add( p.getPermission() ); } sysUser.setPermission( permissionsByUser ); return sysUser; }

4.pom配置

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- shiro 相关包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>${shiro.version}</version> </dependency> <!-- End -->

此处的  ${shiro.version} 使用 1.4.0 版本

5.shiroConfig配置

注意看代码上的注释

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/** * shiro 配置 */ @Configuration public class ShiroConfig { private final static Logger logger = LoggerFactory.getLogger(ShiroConfig.class); // 下面两个方法对 注解权限起作用有很大的关系,请把这两个方法,放在配置的最上面 @Bean(name = "lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); autoProxyCreator.setProxyTargetClass(true); return autoProxyCreator; } //将自己的验证方式加入容器 @Bean public MyRealm myRealm() { System.out.println( "注入 realm" ); MyRealm myRealm = new MyRealm(); return myRealm; } //配置shiro session 的一个管理器 @Bean(name = "sessionManager") public DefaultWebSessionManager getDefaultWebSessionManager(){ DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); // 设置session过期时间 sessionManager.setGlobalSessionTimeout(60*60*1000); return sessionManager; } @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager() { DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); defaultWebSecurityManager.setRealm( myRealm() ); //defaultWebSecurityManager.setSessionManager( getDefaultWebSessionManager() ); return defaultWebSecurityManager; } @Bean public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor( DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } //Filter工厂,设置对应的过滤条件和跳转条件 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { System.out.println( "shiro 过滤器" ); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //拦截器. Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); // 配置不会被拦截的链接 顺序判断 filterChainDefinitionMap.put("/static/**", "anon"); filterChainDefinitionMap.put("/login", "anon"); //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 filterChainDefinitionMap.put("/logout", "logout"); //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了; //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> filterChainDefinitionMap.put("/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login.html"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index.html"); //未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403.html"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } }

6.配置自己的  realm

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/** * 自定义 realm */ public class MyRealm extends AuthorizingRealm { @Autowired private SysUserService sysUserService; @Override public String getName() { return "myRealm"; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { // 从session中获取 user 对象 Session session = SecurityUtils.getSubject().getSession(); SysUser user = (SysUser)session.getAttribute("USER_SESSION"); System.out.println( "执行了================>" ); // 权限信息对象 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addRoles( user.getRoles() ); info.addStringPermissions( user.getPermission() ); Set<String> roles = info.getRoles(); for (String str : roles) { System.out.println( "角色:"+ str ); } Set<String> permissions = info.getStringPermissions(); for (String str : permissions) { System.out.println( "权限:"+ str ); } return info; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //加这一步的目的是在Post请求的时候会先进认证,然后在到请求 if (authenticationToken.getPrincipal() == null) { return null; } String username = (String)authenticationToken.getPrincipal(); String password = new String((char[])authenticationToken.getCredentials()); System.out.println( "username="+username+",password="+password ); // 获取用户名。通过 username 找到该用户 SysUser user = sysUserService.getUserByUserNameWithPermission(username); if( !"1".equals(user.getStatus()) ){ throw new LockedAccountException(); } // 从数据库查询出来的用户名密码,进行验证 // 用户名,密码,密码盐值,realm 名称 // 登陆的时候直接调用 subject.login() 即可自动调用该方法 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo( authenticationToken.getPrincipal() , user.getPassword() , getName() ); Session session = SecurityUtils.getSubject().getSession(); session.setAttribute("USER_SESSION", user); return info; } }

7.方法上加权限

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@RequestMapping("/licm/getMsgById/{id}") @ResponseBody @RequiresPermissions(value = {"msg:find"}) public JsonResult getMsgById(@PathVariable("id")String id){ try { Msg msg = msgService.selectMsgById(id); return new JsonResult(true,msg); } catch (Exception e) { logger.error("查询失败!"); return new JsonResult(false,""); } } @RequestMapping("/licm/getMsgByPage/{start}/{size}") @ResponseBody @RequiresPermissions(value = {"msg:list"}) public JsonResult getMsgById(@PathVariable("start")int start,@PathVariable("size")int size){ try { Map<String , Object> result = msgService.selectListMsgByPage(start,size); return new JsonResult(true, result); } catch (Exception e) { logger.error("查询失败!"); return new JsonResult(false,""); } }

8,运行效果

9.源码地址:

https://github.com/winterme/pkusoft/

最后

以上就是辛勤毛巾最近收集整理的关于SpringBoot整合shiro同时解决注解权限不生效(附源码)1.数据库表设计2.实体:3.查询当前登陆用户方法,获取所有角色,所有权限4.pom配置5.shiroConfig配置6.配置自己的  realm7.方法上加权限8,运行效果9.源码地址:的全部内容,更多相关SpringBoot整合shiro同时解决注解权限不生效(附源码)1.数据库表设计2.实体:3.查询当前登陆用户方法,获取所有角色,所有权限4.pom配置5.shiroConfig配置6.配置自己的 内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部