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小时内删除。