SpringBoot整合shiro同时解决注解权限不⽣效(附源码)1.shiro apache出品的很好⽤的权限框架,理论上来说只需要程序员配置两个类,shiro就能为我们⼯作起来。
这⼏天研究shiro,集成到springboot中,并使⽤注解权限,踩了不少坑,希望这篇⽂章能够帮助到⼤家
本⽂我将讲述⼀下springboot整合shiro,使⽤ @RequiresPermissions 进⾏控制器权限控制
1.数据库表设计
1DROP TABLE IF EXISTS `sys_user`;
2CREATE TABLE `sys_user` (
3 `uid` varchar(36) NOT NULL,
4 `username` varchar(255) DEFAULT NULL,
5 `password` varchar(255) DEFAULT NULL,
6 `password_salt` varchar(255) DEFAULT NULL,
7 `status` varchar(255) DEFAULT NULL,
8 `create_user` varchar(255) DEFAULT NULL,
9 `create_uid` varchar(36) DEFAULT NULL,
10 `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
11 PRIMARY KEY (`uid`)
12) ENGINE=InnoDB DEFAULT CHARSET=utf8;
13
14DROP TABLE IF EXISTS `sys_role_permission`;
15CREATE TABLE `sys_role_permission` (
16 `rid` varchar(36) DEFAULT NULL,
17 `pid` varchar(36) DEFAULT NULL,
shiro安全框架18 `role_name` varchar(255) DEFAULT NULL,
19 `create_user` varchar(255) DEFAULT NULL,
20 `create_uid` varchar(36) DEFAULT NULL,
21 `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP
22) ENGINE=InnoDB DEFAULT CHARSET=utf8;
23
24DROP TABLE IF EXISTS `sys_user_role`;
25CREATE TABLE `sys_user_role` (
26 `id` varchar(36) NOT NULL,
27 `uid` varchar(36) NOT NULL,
28 `rid` varchar(36) NOT NULL,
29 `create_user` varchar(255) DEFAULT NULL,
30 `create_uid` varchar(36) DEFAULT NULL,
31 `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
32 PRIMARY KEY (`id`)
33) ENGINE=InnoDB DEFAULT CHARSET=utf8;
34
35DROP TABLE IF EXISTS `sys_permission`;
36CREATE TABLE `sys_permission` (
37 `pid` varchar(36) NOT NULL,
38 `permission_name` varchar(255) DEFAULT NULL,
39 `permission` varchar(255) DEFAULT NULL,
40 `url` varchar(255) DEFAULT NULL,
41 `create_user` varchar(255) DEFAULT NULL,
42 `create_uid` varchar(36) DEFAULT NULL,
43 `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
44 PRIMARY KEY (`pid`)
45) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.实体:
在user⾥⾯放⼊ roles和permisssion 两个属性,⽤来查询user 的时候⼿动关联查出 该⽤户的⾓⾊和权限
1@Table(name = "sys_user")
2public class SysUser {
3 @Id
4 private String uid;
5
6 private String username;
7
8 private String password;
9
10 @Column(name = "password_salt")
11 private String passwordSalt;
12
13 // 所有的⾓⾊
14 private List<String> roles;
15
16 // 所有的权限
17 private List<String> permission;
18
19 private String status;
20
21 @Column(name = "create_user")
22 private String createUser;
23
24 @Column(name = "create_uid")
25 private String createUid;
26
27 @Column(name = "create_time")
28 private Date createTime;
29
30 .....getset
3.查询当前登陆⽤户⽅法,获取所有⾓⾊,所有权限
1@Override
2 public SysUser getUserByUserNameWithPermission(String username) {
3 // ⽤户名唯⼀,此处⽤⽤户名查出当前⽤户
4 Example example = new Example(SysUser.class);
5 Example.Criteria criteria = ateCriteria();
6 criteria.andEqualTo("username",username);
7 List<SysUser> lists = sysUserMapper.selectByExample(example);
8 if( lists.size()==0 ){
9 return null;
10 }
11
12 SysUser sysUser = (0);
13 // 查出所有的⾓⾊名
14 List<SysRolePermission> roles = Uid());
15 // 查出所有的权限
16 List<SysPermission> permissions = Uid()); 17
18 // roleName
19 List<String> rolesName = new ArrayList<>();
20 for (SysRolePermission role : roles ) {
21 rolesName.add( RoleName() );
22 }
23 sysUser.setRoles( rolesName );
24
25 // permissions
26 List<String> permissionsByUser = new ArrayList<>();
27 for (SysPermission p : permissions) {
28 permissionsByUser.add( p.getPermission() );
29 }
30 sysUser.setPermission( permissionsByUser );
31
32 return sysUser;
33 }
4.pom配置
1 <!-- shiro 相关包 -->
2 <dependency>
3 <groupId>org.apache.shiro</groupId>
4 <artifactId>shiro-core</artifactId>
5 <version>${shiro.version}</version>
6 </dependency>
7 <dependency>
8 <groupId>org.apache.shiro</groupId>
9 <artifactId>shiro-spring</artifactId>
10 <version>${shiro.version}</version>
11 </dependency>
12 <dependency>
13 <groupId>org.apache.shiro</groupId>
14 <artifactId>shiro-ehcache</artifactId>
15 <version>${shiro.version}</version>
16 </dependency>
17 <!-- End -->
此处的 ${shiro.version} 使⽤ 1.4.0 版本
5.shiroConfig配置
注意看代码上的注释
1/**
2 * shiro 配置
3 */
4@Configuration
5public class ShiroConfig {
6
7 private final static Logger logger = Logger(ShiroConfig.class);
8
9 // 下⾯两个⽅法对注解权限起作⽤有很⼤的关系,请把这两个⽅法,放在配置的最上⾯
10 @Bean(name = "lifecycleBeanPostProcessor")
11 public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
12 return new LifecycleBeanPostProcessor();
13 }
14 @Bean
15 public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
16 DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
17 autoProxyCreator.setProxyTargetClass(true);
18 return autoProxyCreator;
19 }
20
21 //将⾃⼰的验证⽅式加⼊容器
22 @Bean
23 public MyRealm myRealm() {
24 System.out.println( "注⼊ realm" );
25 MyRealm myRealm = new MyRealm();
26 return myRealm;
27 }
28
29 //配置shiro session 的⼀个管理器
30 @Bean(name = "sessionManager")
31 public DefaultWebSessionManager getDefaultWebSessionManager(){
32 DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
33 // 设置session过期时间
34 sessionManager.setGlobalSessionTimeout(60*60*1000);
35 return sessionManager;
36 }
37
38 @Bean(name = "securityManager")
39 public DefaultWebSecurityManager getDefaultWebSecurityManager() {
40 DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
41 defaultWebSecurityManager.setRealm( myRealm() );
42 //defaultWebSecurityManager.setSessionManager( getDefaultWebSessionManager() );
43 return defaultWebSecurityManager;
44 }
45
46 @Bean
47 public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(
48 DefaultWebSecurityManager securityManager) {
49 AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
50 advisor.setSecurityManager(securityManager);
51 return advisor;
52 }
53
54 //Filter⼯⼚,设置对应的过滤条件和跳转条件
55 @Bean
56 public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
57 System.out.println( "shiro 过滤器" );
58 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
59 shiroFilterFactoryBean.setSecurityManager(securityManager);
60
61 //.
62 Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
63
64 // 配置不会被拦截的链接顺序判断
65 filterChainDefinitionMap.put("/static/**", "anon");
66 filterChainDefinitionMap.put("/login", "anon");
67 //配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
68 filterChainDefinitionMap.put("/logout", "logout");
69 //<!-- 过滤链定义,从上向下顺序执⾏,⼀般将/**放在最为下边 -->:这是⼀个坑呢,⼀不⼩⼼代码就不好使了;
70 //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
71 filterChainDefinitionMap.put("/**", "authc");
72 // 如果不设置默认会⾃动寻Web⼯程根⽬录下的"/login.jsp"页⾯
73 shiroFilterFactoryBean.setLoginUrl("/login.html");
74 // 登录成功后要跳转的链接
75 shiroFilterFactoryBean.setSuccessUrl("/index.html");
76
77 //未授权界⾯;
78 shiroFilterFactoryBean.setUnauthorizedUrl("/403.html");
79 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
80 return shiroFilterFactoryBean;
81 }
82
83}
6.配置⾃⼰的 realm
1/**
2 * ⾃定义 realm
3 */
4public class MyRealm extends AuthorizingRealm {
5
6 @Autowired
7 private SysUserService sysUserService;
8
9 @Override
10 public String getName() {
11 return "myRealm";
12 }
13
14 @Override
15 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
16 // 从session中获取 user 对象
17 Session session = Subject().getSession();
18 SysUser user = (Attribute("USER_SESSION");
19 System.out.println( "执⾏了================>" );
20 // 权限信息对象
21 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
22 info.addRoles( Roles() );
23 info.addStringPermissions( Permission() );
24
25 Set<String> roles = Roles();
26 for (String str : roles) {
27 System.out.println( "⾓⾊:"+ str );
28 }
29 Set<String> permissions = StringPermissions();
30 for (String str : permissions) {
31 System.out.println( "权限:"+ str );
32 }
33
34
35 return info;
36 }
37
38 @Override
39 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
40 //加这⼀步的⽬的是在Post请求的时候会先进认证,然后在到请求
41 if (Principal() == null) {
42 return null;
43 }
44 String username = (Principal();
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论