关于基于 Spring 安全 URL 的安全性的说明 [重复]

Posted

技术标签:

【中文标题】关于基于 Spring 安全 URL 的安全性的说明 [重复]【英文标题】:Explanation regarding Spring security URL based security [duplicate] 【发布时间】:2019-09-17 12:53:43 【问题描述】:

我有两个 REST 端点:

    /noAuth/rest/sayHi /rest/auth/getMsg

我只想让/rest/auth/getMsg 登录并直接访问/noAuth/rest/sayHi

当我在WebSecurityConfigurerAdapter.configure(HttpSecurity http) 中使用以下模式时

@EnableWebSecurity
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth
            .inMemoryAuthentication()
                .withUser("Java Techie")
                .password("Password")
                .roles("ADMIN");
        auth
            .inMemoryAuthentication()
                .withUser("Basant")
                .password("Password2")
                .roles("USER");
    

    @Override 
    protected void configure(HttpSecurity http) throws Exception 
       http
           .authorizeRequests()
               .antMatchers("/rest/**").authenticated()
               .anyRequest().permitAll()
               .and()
           .httpBasic();
    

我只在/rest/auth/getMsg 中得到登录提示,但在/noAuth/rest/sayHi 中没有,这是预期的。

但是当我使用下面的模式时,我在/rest/auth/getMsg/noAuth/rest/sayHi 都得到了登录提示,这对我来说是非常意外的。

http
    .authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers("/rest/**").permitAll()
        .and()
    .httpBasic();`

我第二次知道我做错了什么,所以我想了解为什么我不能只登录/rest/auth/getMsg 并直接访问/noAuth/rest/sayHi

更新

@nully 这有点道理,但打破了我对其他情况的理解。假设我使用这种模式:

http
    .authorizeRequests()
        .anyRequest().authenticated()
        .anyRequest().hasRole("ADMIN")
        .and()
    .httpBasic();`

只允许 user = "Java Techie" 登录,因为它是 ADMIN 并为 user = "Basant" 抛出 403 Forbidden

但是当我使用

http
    .authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers("/rest/**").hasRole("ADMIN")
        .and()
    .httpBasic();

根据您的解释,它不应该允许 user = "Basant" 访问 /rest/auth/getMsg,因为它有 role = "USER"。但实际上,当我使用 user = "Basant" 时,它允许我访问 /rest/auth/getMsg

【问题讨论】:

所以堆栈溢出要求我标记您的答案“这解决了我的问题”!什么给你任何代表?否则你可以在这里发布你的答案,我可以在这里接受答案 不要担心接受答案。可能的重复链接将重定向人们,或者您的问题稍后将被删除。 @ASharma7 不,您不能接受我在另一个问题中的回答。您只能在自己的问题中接受答案。但是您可以支持我的回答(我认为您已经这样做了)。是的,如果我在你接受的问题中写下另一个答案,我会得到额外的代表。但这不是我喜欢的方式。一些用户对同一用户的重复答案投了反对票。 过滤器/安全规则的顺序很重要。您首先要求对所有内容进行身份验证,然后进行排除。您应该切换顺序,首先进行所有特定匹配,然后进行更全局的匹配。规则按照定义的顺序进行查询,第一个匹配项是将被选中的匹配项。在这种情况下,请始终进行身份验证。 【参考方案1】:

默认情况下,如果没有其他规则,则要求进行身份验证。您应该添加类似antMatchers("/noAuth/**").permitAll() 的内容。

【讨论】:

我为“/noAuth/** 添加了,但我仍然在登录 /noAuth/rest/sayHi --”http.authorizeRequests().anyRequest().authenticated().antMatchers(" /rest/**").permitAll().antMatchers("/noAuth/**").permitAll().and().httpBasic();【参考方案2】:

执行是从左到右的。在第一种情况下:.antMatchers("/rest/").authenticated(),所以验证任何匹配 rest/

在第 2 种情况下:.anyRequest().authenticated(),因此任何请求都将在继续之前获得所需的身份验证。

【讨论】:

我会尽量保持简单:http.authorizeRequests().antMatchers("/rest/**").access("hasRole('ADMIN')");应该管用。不幸的是,我不是 springboot 专家,所以我尽量保持简短明了。 这个我知道它工作正常。只是想了解为什么第二个不起作用。谢谢你的时间。感谢您的帮助。

以上是关于关于基于 Spring 安全 URL 的安全性的说明 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Spring 安全登录 - 使用外部数据库的基于注释的配置

如何避免自定义过滤器在spring-security中为不安全的url运行

Spring Security 使用基于xml的http认证

Spring Security

Spring Security 学习总结

Spring 安全忽略 url 不适用于我们的安全忽略方法 [重复]