弹簧靴&x2B;Spring Security+;等级角色

弹簧靴&x2B;Spring Security+;等级角色,spring,spring-security,spring-boot,Spring,Spring Security,Spring Boot,我试图在我的Spring Boot应用程序中设置分层角色,但没有成功。我已经完成了互联网上不同地方所说的一切。但是没有一个我能解决这个问题 下面是我的SecurityConfig类的代码。当我使用角色为_ADMIN的用户登录应用程序时,它应该能够从“/users”检索数据,但当前我收到一个访问被拒绝的异常。如果用户具有角色\u用户凭据,则可以正常工作。 有人能帮我找出失败的地方吗? 提前谢谢 @Configuration @EnableWebMvcSecurity @EnableGlobalMe

我试图在我的Spring Boot应用程序中设置分层角色,但没有成功。我已经完成了互联网上不同地方所说的一切。但是没有一个我能解决这个问题

下面是我的SecurityConfig类的代码。当我使用角色为_ADMIN的用户登录应用程序时,它应该能够从“/users”检索数据,但当前我收到一个访问被拒绝的异常。如果用户具有角色\u用户凭据,则可以正常工作。 有人能帮我找出失败的地方吗? 提前谢谢

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private SigpaUserDetailsService userDetailsService;

    @Bean
    public RoleHierarchyImpl roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
        return roleHierarchy;
    }

    @Bean
    public RoleHierarchyVoter roleVoter() {     
        return new RoleHierarchyVoter(roleHierarchy());
    }

    @Bean 
    public DefaultWebSecurityExpressionHandler expressionHandler(){
        DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();
        expressionHandler.setRoleHierarchy(roleHierarchy());
        return expressionHandler;
    }

    @Bean
    @SuppressWarnings(value = { "rawtypes" })
    public AffirmativeBased accessDecisionManager() {       
        List<AccessDecisionVoter> decisionVoters = new ArrayList<AccessDecisionVoter>();
        WebExpressionVoter webExpressionVoter = new WebExpressionVoter();
        webExpressionVoter.setExpressionHandler(expressionHandler());
        decisionVoters.add(webExpressionVoter);
        decisionVoters.add(roleVoter());
        return new AffirmativeBased(decisionVoters);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .accessDecisionManager(accessDecisionManager())
            .expressionHandler(expressionHandler())
            .antMatchers("/users/**")
                .access("hasRole('ROLE_USER')")
            .anyRequest().authenticated();
        http
            .formLogin()
                .loginPage("/login").permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder registry)
            throws Exception {
        registry.userDetailsService(userDetailsService);
    }
}
@配置
@启用WebMVC安全性
@EnableGlobalMethodSecurity(securedEnabled=true,Prespenabled=true)
公共类WebSecurityConfig扩展了WebSecurityConfigureAdapter{
@自动连线
私有SigpaUserDetailsService用户详细信息服务;
@豆子
公共角色层级Yimpl角色层级(){
RoleHierarchyImpl roleHierarchy=新的RoleHierarchyImpl();
setHierarchy(“角色管理>角色用户”);
回归角色层级制;
}
@豆子
public RoleHierarchyVoter roleVoter(){
返回新的RoleHierarchyVoter(roleHierarchy());
}
@豆子
public DefaultWebSecurityExpressionHandler expressionHandler(){
DefaultWebSecurityExpressionHandler expressionHandler=新的DefaultWebSecurityExpressionHandler();
setRoleHierarchy(roleHierarchy());
返回表达式处理程序;
}
@豆子
@SuppressWarnings(值={“rawtypes”})
基于公共确认的accessDecisionManager(){
列表决策投票者=新的ArrayList();
WebExpressionVoter WebExpressionVoter=新的WebExpressionVoter();
setExpressionHandler(expressionHandler());
decisionvorters.add(webexpressionvorter);
添加(roleVoter());
返回新的基于确认的(决策投票者);
}
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
http
.授权请求()
.accessDecisionManager(accessDecisionManager())
.expressionHandler(expressionHandler())
.antMatchers(“/users/**”)
.access(“hasRole('ROLE\u USER')”)
.anyRequest().authenticated();
http
.formLogin()
.loginPage(“/login”).permitAll()
.及()
.logout()
.permitAll();
}
@凌驾
受保护的无效配置(AuthenticationManagerBuilder注册表)
抛出异常{
registry.userDetailsService(userDetailsService);
}
}

更新:这是根据您的建议更新的代码,但仍然不起作用。

您需要在web上设置角色层次结构。比如:

DefaultWebSecurityExpressionHandler expressionHandler=新的DefaultWebSecurityExpressionHandler();
setRoleHierarchy(roleHierarchy);
setExpressionHandler(expressionHandler);
更新:您也可以尝试如下设置上述表达式处理程序:

http
.授权请求()
.expressionHandler(expressionHandler)
...

您必须在MethodSecurityExpressionHandler上设置角色层次结构:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Autowired
    private RoleHierarchy roleHierarchy;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        final DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
        handler.setRoleHierarchy(this.roleHierarchy);
        return handler;
    }
}

查看更多信息。特别注意:启用的GlobalMethodSecurity仍然必须包含在类扩展GlobalMethodSecurity配置中,以确定设置。

我刚刚完成了这些设置,因此肯定会让您现在开始运行。交易如下:

您引入了此注释
@EnableGlobalMethodSecurity(securedEnabled=true,Preprestenabled=true)
,但没有显示任何使用预/后授权/筛选的代码,因此我不知道您是否真的需要它

  • 如果您不需要该类/方法级别的安全性/筛选,则只需执行以下操作:

    @Bean
    public RoleHierarchyImpl roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
        return roleHierarchy;
    }
    
  • }

    我将给这个新类命名为GlobalMethodSecurityConfig,并将当前的GlobalMethodSecurityConfig类更改为WebSecurityConfig或其他内容,以反映它是web层的安全设置

    我在webSecurityConfig中定义
    roleherarchy
    bean,并在globalMethodSecurityConfig中注入/使用它,但您可以按照自己喜欢的方式来做,只要您不需要创建两个bean


    希望这有帮助。

    启用方法级安全性(即@EnableGlobalMethodSecurity(prespenabled=true))以及支持WebSecurity配置适配器上的分层角色

    1.只需在用@Bean注释的任何其他类上分离角色层次结构
    2.使用@Autowired on websecurity配置适配器注入它。 它在我的项目中完美地工作

    请检查一下我的代码

    WeSecurityConfig.class

    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @EnableWebSecurity
    public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private RoleHierarchy roleHierarchy;
    
        private SecurityExpressionHandler<FilterInvocation>    webExpressionHandler() {
            DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler     = new DefaultWebSecurityExpressionHandler();
            defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy);
            return defaultWebSecurityExpressionHandler;
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            super.configure(web);
            web.ignoring().antMatchers("/static/**");
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.
                authorizeRequests()
                .expressionHandler(webExpressionHandler())
                .antMatchers("/static/**","/bower_components/**","/").permitAll()
                .antMatchers("/user/login","/user/login?error").anonymous()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/user/login").passwordParameter("password").usernameParameter("username")
                .defaultSuccessUrl("/")
                .permitAll()
                .and()
                .logout().logoutUrl("/user/logout")
                .logoutSuccessUrl("/user/login?logout")
                .and().csrf();
    
        }
    
        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(daoAuthenticationProvider());
        }
    
        public DaoAuthenticationProvider daoAuthenticationProvider(){
            final DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
            auth.setUserDetailsService(userDetailService);
            auth.setPasswordEncoder(passwordEncoder);
            return auth;
        }
    }
    

    希望对您有所帮助。

    我们可以清楚地看到RoleHierarchyImpl类的setHierarchy方法。他们正在用“\n”拆分多个层次结构角色

    @Bean
    public RoleHierarchyImpl roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_WRITER\n" +
                "ROLE_ADMIN > ROLE_EDITOR");
        return roleHierarchy;
    }
    

    这样不行。我仍然收到相同的访问被拒绝例外我昨天已经这样做了。。。我不知道为什么不工作,因为我已经做了所有可能的事情,但没有成功。在这个
    http上搜索了几个小时后。authorizeRequests().expressionHandler(expressionHandler)
    workedHi,感谢您的回答!不幸的是,Spring不允许我从我的
    WebSecurityConfig
    类中删除
    @EnableGlobalMethodSecurity
    注释-我得到
    IllegalArgumentException:配置默认servlet处理需要ServletContext
    。感谢任何帮助好的,我找到了解决办法。看起来像你在第二点的建议。不是很好,因为对我来说,情况正好相反。请看下面的答案:我无法运行此代码。当像在您的示例中那样重写
    globalMethodSecurity配置
    类时,我得到
    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @EnableWebSecurity
    public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private RoleHierarchy roleHierarchy;
    
        private SecurityExpressionHandler<FilterInvocation>    webExpressionHandler() {
            DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler     = new DefaultWebSecurityExpressionHandler();
            defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy);
            return defaultWebSecurityExpressionHandler;
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            super.configure(web);
            web.ignoring().antMatchers("/static/**");
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.
                authorizeRequests()
                .expressionHandler(webExpressionHandler())
                .antMatchers("/static/**","/bower_components/**","/").permitAll()
                .antMatchers("/user/login","/user/login?error").anonymous()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/user/login").passwordParameter("password").usernameParameter("username")
                .defaultSuccessUrl("/")
                .permitAll()
                .and()
                .logout().logoutUrl("/user/logout")
                .logoutSuccessUrl("/user/login?logout")
                .and().csrf();
    
        }
    
        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(daoAuthenticationProvider());
        }
    
        public DaoAuthenticationProvider daoAuthenticationProvider(){
            final DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
            auth.setUserDetailsService(userDetailService);
            auth.setPasswordEncoder(passwordEncoder);
            return auth;
        }
    }
    
    @Configuration
    public class BeanConfiguration {
    
        @Bean
        public RoleHierarchy roleHierarchy() {
            RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
            /* tricks lies here */
            roleHierarchy.setHierarchy("ROLE_SUPREME > ROLE_ADMIN ROLE_ADMIN > ROLE_OPERATOR ROLE_OPERATOR > ROLE_GUEST");
            return roleHierarchy;
        }
    }
    
    @Bean
    public RoleHierarchyImpl roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_WRITER\n" +
                "ROLE_ADMIN > ROLE_EDITOR");
        return roleHierarchy;
    }