【问题标题】:Spring Security ignoring rolesSpring Security 忽略角色
【发布时间】:2021-01-14 13:42:57
【问题描述】:

我有这个控制器:

@RestController
public class NumbersController {

    @PreAuthorize("hasRole('ROLE_ONE')")
    @GetMapping("/one")
    private String one(){
        return "This is one.";
    }

    @PreAuthorize("hasRole('ROLE_TWO')")
    @GetMapping("/two")
    private String two(){
        return "This is two.";
    }
}

还有这个安全配置:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends GlobalMethodSecurityConfiguration {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        auth
                .inMemoryAuthentication()
                .withUser("user").password(encoder.encode("password")).roles("ONE");
        auth
                .inMemoryAuthentication()
                .withUser("user2").password(encoder.encode("password2")).roles("TWO");
    }

}

在运行时,我的两个用户都可以访问这两种资源。我想要的只是user 能够访问/one 并且只有user2 才能访问/two。 我也尝试使用@Secured("ONE") 得到相同的结果。

控制台输出:

2021-01-14 16:10:20.026  INFO 4376 --- [           main] security.security.SecurityApplication    : Starting SecurityApplication on Ivan-PC with PID 4376 (D:\Z\security\target\classes started by Ivan in D:\Z\security)
2021-01-14 16:10:20.041  INFO 4376 --- [           main] security.security.SecurityApplication    : No active profile set, falling back to default profiles: default
2021-01-14 16:10:24.363  INFO 4376 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-01-14 16:10:24.378  INFO 4376 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-01-14 16:10:24.378  INFO 4376 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-01-14 16:10:24.565  INFO 4376 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-01-14 16:10:24.565  INFO 4376 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4321 ms
2021-01-14 16:10:25.221  INFO 4376 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-01-14 16:10:25.860  INFO 4376 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@57a48985, org.springframework.security.web.context.SecurityContextPersistenceFilter@17740dae, org.springframework.security.web.header.HeaderWriterFilter@14bf57b2, org.springframework.security.web.csrf.CsrfFilter@48535004, org.springframework.security.web.authentication.logout.LogoutFilter@3cee53dc, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@67440de6, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@35835e65, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@1ab6718, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@7ce7e83c, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@345cf395, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@7144655b, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3910fe11, org.springframework.security.web.session.SessionManagementFilter@14379273, org.springframework.security.web.access.ExceptionTranslationFilter@cfbc8e8, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@49293b43]
2021-01-14 16:10:25.969  INFO 4376 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-01-14 16:10:25.985  INFO 4376 --- [           main] security.security.SecurityApplication    : Started SecurityApplication in 6.771 seconds (JVM running for 8.031)
2021-01-14 16:10:29.847  INFO 4376 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-01-14 16:10:29.848  INFO 4376 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-01-14 16:10:29.870  INFO 4376 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 22 ms

邮递员向http://localhost:8080/two 发出请求并使用授权字段。

【问题讨论】:

  • 几件事,发布您的完整调试日志,还发布您的通话方式。方法安全仅用于调用方法时使用 AOP 安全,如果你在做 http rest 调用你需要配置HttpSecurity。投票关闭调试信息太少。
  • 配置HttpSecurity 成功了。

标签: spring spring-boot spring-security


【解决方案1】:

如果有帮助,请检查,

我们可以配置多个 HttpSecurity 实例,就像我们可以拥有多个块一样。关键是多次扩展 WebSecurityConfigurerAdapter。例如,以下是对以 /api/ 开头的 URL 进行不同配置的示例。

@EnableWebSecurity
public class MultiHttpSecurityConfig {
    @Bean                                                             
    public UserDetailsService userDetailsService() throws Exception {
        // ensure the passwords are encoded properly
        UserBuilder users = User.withDefaultPasswordEncoder();
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(users.username("user").password("password").roles("USER").build());
        manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build());
        return manager;
    }
@Configuration
@Order(1)                                                        
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/api/**")                               
            .authorizeRequests(authorize -> authorize
                .anyRequest().hasRole("ADMIN")
            )
            .httpBasic(withDefaults());
    }
}

@Configuration                                                   
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests(authorize -> authorize
                .anyRequest().authenticated()
            )
            .formLogin(withDefaults());
    }
}
}

正常配置身份验证 创建一个包含 @Order 的 WebSecurityConfigurerAdapter 实例,以指定应首先考虑哪个 WebSecurityConfigurerAdapter。 http.antMatcher 声明此 HttpSecurity 仅适用于以 /api/ 开头的 URL 创建另一个 WebSecurityConfigurerAdapter 实例。 如果 URL 不以 /api/ 开头,则将使用此配置。 此配置在 ApiWebSecurityConfigurationAdapter 之后考虑,因为它在 1 之后有一个 @Order 值(没有 @Order 默认为最后一个)。

【讨论】:

  • 问题是我没有使用 HttpSecurity,它现在可以工作了。
【解决方案2】:

在你的 SecurityConfig 课堂上试试这个

@EnableGlobalMethodSecurity(
      prePostEnabled = true,  
      jsr250Enabled = true)
  • prePostEnabled 属性启用 Spring Security 前/后注释
  • jsr250Enabled 属性允许我们使用@RoleAllowed 注解

【讨论】:

  • 还是一样。
  • 这对我有用。你能再核对一下吗!
  • 是的,仍然没有。我觉得这与角色分配有关,我将检查一下。感谢您的帮助。
猜你喜欢
  • 2014-10-05
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2016-08-15
  • 1970-01-01
  • 2014-12-26
  • 2012-08-15
相关资源
最近更新 更多