security3权限管理:SecurityMetadataSource不支持FilterInvocation?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了security3权限管理:SecurityMetadataSource不支持FilterInvocation?相关的知识,希望对你有一定的参考价值。

Caused by: java.lang.IllegalArgumentException: SecurityMetadataSource does not support secure object class: class org.springframework.security.web.FilterInvocation
at org.springframework.util.Assert.isTrue(Assert.java:65)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:123)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
... 46 more

pad在学校的电脑里建立一个隐藏的超级帐户:
1、在开始/运行中输入:regedt32.exe并回车来运行regedt32.exe。

2、点“权限”以后会弹出窗口点添加将我登录时的帐户添加到安全栏内,这里我是以administrator的身份登录的,所以我就将administrator加入,并设置权限为“完全控制"。这里需要说明一下:最好是添加你登录的帐户或帐户所在的组,切莫修改原有的帐户或组,否则将会带来一系列不必要的问题。等隐藏超级用户建好以,再来这里将你添加的帐户删除即可。

3、再点“开始”→“运行”并输入"regedit.exe" 回车,启动注册表编辑器regedit.exe。 打开键:HKEY_LOCAL_MAICHINESAMSAMDomainsaccountusernameshacker$"

4、将项hacker$、00000409、000001F4导出为hacker.reg、409.reg、1f4.reg,用记事本分别打这几个导出的文件进行编辑,将超级用户对应的项000001F4下的键"F"的值复制,并覆盖hacker$对应的项00000409下的键"F"的值,然后再将00000409.reg与hacker.reg合并。

5、在命令行下执行net user hacker$ /del将用户hacker$删除:net user hacker$ /del

6、在regedit.exe的窗口内按F5刷新,然后打文件-导入注册表文件将修改好的hacker.reg导入注册表即可

7、到此,隐藏的超级用户hacker$已经建好了,然后关闭regedit.exe。在regedt32.exe窗口内把HKEY_LOCAL_MACHINESAMSAM键权限改回原来的样子(只要删除添加的帐户administrator即可)。

8、注意:隐藏的超级用户建好后,在帐户管理器看不到hacker$这个用户,在命令行用“net user”命令也看不到,但是超级用户建立以后,就不能再改密码了,如果用net user命令来改hacker$的密码的话,那么在帐户管理器中将又会看这个隐藏的超级用户了,而且不能删除。dws追问

这位兄弟,谢谢的详细说明,但是我问的是java spring security3安全控制框架的问题,跟你上面说的好像对不上吧?

参考技术A 这里面是用户定义资源安全元数据源的 用来加载所谓的资源及对应的权限的一个list集合
类似 public Collection<ConfigAttribute> getAttributes(Object obj)
返回的是用户请求的资源(/index.jsp)所需要的权限集合本回答被提问者采纳
参考技术B oxd看晕了吧,这么多,呵呵,这些人真的不负责,随便 复制粘贴就了事了pjt追问

??? 不明白你说的什么意思。

是说的下面的这位回答者么?

Spring Security 权限管理

概述

权限是大部分的后台管理系统都需要实现的功能,用户控制不同的角色能够进行的不同的操作。Spring Security的可以进行用户的角色权限控制,也可以进行用户的操作权限控制。在之前的代码实现上,我们仅仅只是实现用户的登录,在用户信息验证的时候使用UserDetailsService,但是却一直忽略了用户的权限。

一. 启动类配置

/**
 * 开启方法的注解安全校验。
 *  securedEnabled  @Secured("ROLE_abc")  该注解是Spring security提供的
 *  jsr250Enabled  @RolesAllowed("admin")  该注解是 JSR250 支持的注解形式
 *  prePostEnabled @PreAuthorize("hasAuthority(‘user:add‘)
 */
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class SecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SecurityApplication.class, args);
    }
}

二. 基于角色的权限控制

2.1 自定义认证信息类, 查询用户的密码和权限

@Component
public class UserSecurityService implements UserDetailsService {


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        /**
         * 调用形式有两种:
         *   1. 此时构建的 SimpleGrantedAuthority 必须是以 ROLE_ 开头, 例如 ROLE_admin, ROLE_manager.
         *      实现全权限控制的时候使用 @RolesAllowed("ROLE_admin")  或者 @RolesAllowed("admin") 都可以
         *   2. 此时构建的 SimpleGrantedAuthority 必须是以 ROLE_ 开头, 例如 ROLE_admin, ROLE_manager.
         *     实现全权限控制的时候使用 @Secured("ROLE_admin") ROLE_是不能省略的。
         */
        return new User(username, sysUser.getPassword(),
                Arrays.asList(new SimpleGrantedAuthority("ROLE_admin")));
    }
}

注意: 我们在构建SimpleGrantedAuthority对象的时候,用户的角色必须是以 ROLE_ 开头,例如 ROLE_adminROLE_manager

2.2 角色权限控制使用

在控制器上进行用户访问控制的时候,基于角色有两种书写方式:

方式一:@RolesAllowed

/**
 *  @RolesAllowed 中的值可以写成 "admin", 例如 @RolesAllowed("admin")
 *  推荐: @RolesAllowed 中的值还可以写成 "ROLE_admin",例如 @RolesAllowed("ROLE_admin")
 */
@RequestMapping
@RolesAllowed("admin")
public Object getAll() {
    return Arrays.asList(new User(10, "张"), new User(20, "李四"));
}

方式二:@Secured

/**
 *  @Secured 中的值必须为 "ROLE_admin",例如 @Secured("ROLE_admin"),ROLE_不能省略
 */
@RequestMapping
@Secured("ROLE_admin")
public Object getAll() {
    return Arrays.asList(new User(10, "张"), new User(20, "李四"));
}

三. 基于操作的权限控制

当然我们也可以使用基于操作的权限控制,这个功能稍显得有点累赘,因为在实际的项目开发过程中我们都是基于角色的权限控制。

3.1 自定义认证信息类, 查询用户的密码和权限

@Component
public class UserSecurityService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
         /**
         *  A. new SimpleGrantedAuthority("user:delete")   @PreAuthorize("hasAnyAuthority(‘user:add‘, ‘user:list‘)") 无法访问。
         *  B. new SimpleGrantedAuthority("user:add")     @PreAuthorize("hasAnyAuthority(‘user:add‘, ‘user:list‘)") 可以访问。
         *  C. Arrays.asList(new SimpleGrantedAuthority("user:add"), new SimpleGrantedAuthority("user:list"))
         *     @PreAuthorize("hasAuthority(‘user:add‘) and hasAuthority(‘user:list‘)") 可以访问
         *  D. new SimpleGrantedAuthority("ROLE_admin") 定义角色
         *    @PreAuthorize("hasRole(‘admin‘)")  可以访问
         */
        return new User(username, sysUser.getPassword(),
                Arrays.asList(new SimpleGrantedAuthority("user:list"),
                new SimpleGrantedAuthority("user:add")
                ));
    }
}

3.2 控制器访问控制(针对角色)

/**
 *  @PreAuthorize 中的值可以为 "ROLE_admin", "admin",
 *  例如 @PreAuthorize("hasRole(‘admin‘)") 或者为  
 *      @PreAuthorize("hasRole(‘ROLE_admin‘)")
 */
@RequestMapping
@PreAuthorize("hasRole(‘admin‘)")
public Object getAll() {
    return Arrays.asList(new User(10, "张"), new User(20, "李四"));
}

3.3 控制器访问控制(针对操作)

@RequestMapping
// @PreAuthorize("hasAuthority(‘user:add‘) and hasAuthority(‘user:list‘)") 
// @PreAuthorize("hasAuthority(‘user:add‘) or hasAuthority(‘user:list‘)")
@PreAuthorize("hasAnyAuthority(‘user:add‘, ‘user:list‘)") 
public Object getAll() {
    return Arrays.asList(new User(10, "张"), new User(20, "李四"));
}

3.4 访问无权限处理

.and()
.exceptionHandling()
.accessDeniedHandler(customizeAccessDeniedHandler)  //无权限访问处理, customizeAccessDeniedHandler为无权限处理操作类
.and()

四 .示例

4.1 用户权限表设计

 
技术图片
 

sql脚本

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `permmit` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_permission
-- ----------------------------
BEGIN;
INSERT INTO `sys_permission` VALUES (1, ‘删除用户‘, ‘user:delete‘);
INSERT INTO `sys_permission` VALUES (2, ‘展示用户‘, ‘user‘);
INSERT INTO `sys_permission` VALUES (3, ‘添加用户‘, ‘user:add‘);
INSERT INTO `sys_permission` VALUES (4, ‘编辑用户‘, ‘user:edit‘);
INSERT INTO `sys_permission` VALUES (5, ‘导出用户‘, ‘user:export‘);
INSERT INTO `sys_permission` VALUES (6, ‘部门展示‘, ‘dept‘);
INSERT INTO `sys_permission` VALUES (7, ‘删除部门‘, ‘dept:delete‘);
COMMIT;

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(20) NOT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
BEGIN;
INSERT INTO `sys_role` VALUES (1, ‘admin‘, ‘系统管理员‘);
INSERT INTO `sys_role` VALUES (2, ‘finance‘, ‘财务管理‘);
INSERT INTO `sys_role` VALUES (3, ‘administration ‘, ‘行政管理‘);
COMMIT;

-- ----------------------------
-- Table structure for sys_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
  `role_id` int(11) NOT NULL,
  `permission_id` int(11) NOT NULL,
  PRIMARY KEY (`role_id`,`permission_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_role_permission
-- ----------------------------
BEGIN;
INSERT INTO `sys_role_permission` VALUES (1, 1);
INSERT INTO `sys_role_permission` VALUES (1, 2);
INSERT INTO `sys_role_permission` VALUES (1, 3);
INSERT INTO `sys_role_permission` VALUES (1, 4);
INSERT INTO `sys_role_permission` VALUES (1, 5);
INSERT INTO `sys_role_permission` VALUES (1, 6);
INSERT INTO `sys_role_permission` VALUES (1, 7);
INSERT INTO `sys_role_permission` VALUES (2, 2);
INSERT INTO `sys_role_permission` VALUES (2, 5);
INSERT INTO `sys_role_permission` VALUES (2, 6);
INSERT INTO `sys_role_permission` VALUES (3, 2);
INSERT INTO `sys_role_permission` VALUES (3, 6);
COMMIT;

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` int(11) NOT NULL,
  `username` char(20) DEFAULT NULL,
  `password` char(100) DEFAULT NULL,
  `mobile` char(15) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
BEGIN;
INSERT INTO `sys_user` VALUES (1, ‘jack‘, ‘$2a$10$GqJuJhe7zmtwwThIed7smu9zMJBgSQzFMP47eEDL.g9tg8Y82.A7m‘, ‘13268050688‘);
INSERT INTO `sys_user` VALUES (2, ‘rose‘, ‘$2a$10$GqJuJhe7zmtwwThIed7smu9zMJBgSQzFMP47eEDL.g9tg8Y82.A7m‘, ‘13268050688‘);
COMMIT;

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`user_id`,`role_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
BEGIN;
INSERT INTO `sys_user_role` VALUES (1, 1);
INSERT INTO `sys_user_role` VALUES (2, 2);
INSERT INTO `sys_user_role` VALUES (2, 3);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

4.2 service层

4.3 用户权限的查询

// 该类的作用是处理用户登录名和密码
@Component
public class UserSecurityService implements UserDetailsService {
    private static Logger logger = LoggerFactory.getLogger(UserSecurityService.class);
    @Resource
    private SysUserService sysUserService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        logger.info("用户名或者电话:" + username);
        SysUser sysUser = null;
        try{
            sysUser = sysUserService.getSysUserByUsenameOrMobile(username);
        }catch (EmptyResultDataAccessException exception) {  //没有对应的用户名异常
            throw new UsernameNotFoundException("用户或密码错误");
        }
        if(null == sysUser) {
            throw new UsernameNotFoundException("用户名或密码错误");
        }else {
            /**
             * User第一参数是:用户名
             *     第二个参数是:pssword, 是从数据库查出来的
             *     第三个参数是: 权限
             */
            User user =  null;
            try{
                user = new User(username,
                        sysUser.getPassword(),
//                        getAuthorities(sysUser.getRoles()));
                        getMethodsAuthorities(sysUser.getPermissions()));
            }catch (InternalAuthenticationServiceException exception) {
                throw exception;  // 在此处,将异常接着往外抛,抛给AuthenticationFailureHandler处理
            }
            return user;
        }
    }
    // [new SimpleGrantedAuthority("user:list"), new SimpleGrantedAuthority("user:add")]
    private List<SimpleGrantedAuthority> getMethodsAuthorities(Set<String> permissions) {
        List<SimpleGrantedAuthority> list = new ArrayList<>();
        if(null != permissions && permissions.size() > 0){
            permissions.forEach(permission -> {
                SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(permission); // user:list dept:list
                list.add(simpleGrantedAuthority);
            });
        }
        return list;
    }
    // [new SimpleGrantedAuthority("ROLE_admin"), new SimpleGrantedAuthority("ROLE_xxx")]
    // 封装用户角色权限
    private List<SimpleGrantedAuthority> getAuthorities(Set<String> roles) {
        List<SimpleGrantedAuthority> list = new ArrayList<>();
       if(null != roles && roles.size() > 0){
            roles.forEach(role -> {
                SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("ROLE_" + role);
                list.add(simpleGrantedAuthority);
            });
        }
        return list;
    }
}

4.4 Controller层

// @RolesAllowed("admin")
@RequestMapping("/user")
@Controller
public class UserController {

    /**
     * This annotation can be specified on a class or on method(s). Specifying it
     *  at a class level means that it applies to all the methods in the class.
     *  Specifying it on a method means that it is applicable to that method only.
     *
     * @RolesAllowed  可以写的值 ROLE_admin  admin
     *
     * he <code>Secured</code> annotation is used to define a list of security configuration
     *  attributes for business methods.
     * @Secured  只支持ROLE_admin  尽量用在service中。
     */
    @RequestMapping
    // @RolesAllowed("admin")
    // @Secured({"ROLE_admin", "ROLE_finance"})
    // @PreAuthorize("hasAuthority(‘user:list‘)")
    public Object get() {
        return "/index.html";
    }


    @ResponseBody
    @RequestMapping("/list")
    // @PreAuthorize("hasRole(‘ROLE_admin‘)")
    //@RolesAllowed({"admin", "finance", "administration "})
    // @PreAuthorize("hasRole(‘admin‘) or hasRole(‘finance‘)")
    // @PreAuthorize("hasRole(‘admin‘) and hasRole(‘finance‘)")  //表是同时拥有这两个角色才能访问
    // @PreAuthorize("hasAnyRole(‘admin‘, ‘finance‘)")  //与上面的属性形式一样
    // @PreAuthorize("hasAuthority(‘user:list‘)") //3个用户都有这个权限
    public Object list() {
        return "list";
    }

    @ResponseBody
    @RequestMapping("/delete")
    // @PreAuthorize("hasAuthority(‘user:delete‘)") //只有jack
    public Object delete() {
        return "delete";
    }

    @ResponseBody
    @RequestMapping("/export")
    // @PreAuthorize("hasAuthority(‘user:export‘)") // 只有rose, jack
    public Object export() {
        return "export";
    }
}



以上是关于security3权限管理:SecurityMetadataSource不支持FilterInvocation?的主要内容,如果未能解决你的问题,请参考以下文章

spring security3 动态从数据库中读取权限信息<sec:authorize>标签 url属性不起作用

Spring Security3.0怎样自定义登录,后台自定义参数传递

Spring3,Security3:系统可以在 Windows 上运行,但不能在 Linux 上运行 java.lang.IllegalArgumentException

spring security3替换默认过滤器,报错,求助

Spring Security3中的-authentication-manager标签详解

在spring security3中解析memberOf属性以获取组