使用 Spring 安全过滤器锁定除少数路由之外的所有内容

Use Spring Security Filter to lock down everything except a few routes

我们正在重新设计我们的产品以删除 SpringSecurity 中的默认 "anonymousUser" 行为,并希望锁定除少数端点之外的所有 URL(通过过滤器安全性)。我们想不通的是如何指定 "lock down everything except X, Y, and Z"

我们的安全设置基本上归结为以下几点:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // disable anonymous users
            .anonymous().disable()

            // don't add ROLE_ to the role...
            .authorizeRequests()
                .regexMatchers("^/", "^/login", "^/mobile/login", "^/api/auth/.*")
                    .authenticated()
                .and()  
        ;
    }
}

我走过的其他路线类似于:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // disable anonymous users
            .anonymous().disable()

            // don't add ROLE_ to the role...
            .authorizeRequests()
            .antMatchers("/**")
                .authenticated()
            .antMatchers("/", "/login", "/mobile/login", "/api/auth/**", "/reservations/**")
                .permitAll()
            .and()
        ;
    }
}

如有任何建议/意见,我们将不胜感激。

谢谢!

如果你使用 security.xml 我知道你可以做这样的事情

<http use-expressions="true" entry-point-ref="authenticationEntryPoint">
    <custom-filter position="BASIC_AUTH_FILTER" ref="loginFilter" />
    <intercept-url pattern="/login" access="permitAll" />
    <intercept-url pattern="/mobile/login" access="permitAll" />
    <intercept-url pattern="/api/auth/**" access="fullyAuthenticated" />
    <intercept-url pattern="/**" access="fullyAuthenticated" />
    <logout success-handler-ref="logoutHandler" />
</http>

它的作用是允许任何人访问登录或 mobile/login 但只允许经过完全验证的人访问 api/auth 或网站上的任何其他内容

<intercept-url pattern="/api/auth/**" access="fullyAuthenticated" />

可以删除此行,并且可以使用相同的功能。它从上到下开始,因此顶部允许的任何内容都优先。

We're reworking our product to remove the default "anonymousUser" behavior in Spring Security

我想知道你这是什么意思。根据其余描述,我认为您不需要以下内容(即您应该删除它):

anonymous().disabled()

上面说如果没有用户认证,用户会是null,这往往会导致NullPointerExceptions。

请记住 authorizeRequests()(或 <intercept-url>顺序很重要。您拥有的 Java 配置(针对 readability 稍微重新格式化)

.authorizeRequests()
    .antMatchers("/**").authenticated()
    .antMatchers("/", "/login", "/mobile/login", "/api/auth/**", "/reservations/**").permitAll()
    .and()

将使用以下逻辑:

  • 这个请求是否匹配“/**”?
    • 是的,一切都匹配“/**”。所以每个请求都需要对用户进行身份验证。
  • 忽略所有其他规则,因为我们已经匹配

您应该使用以下内容:

.authorizeRequests()
    .antMatchers("/", "/login", "/mobile/login", "/api/auth/**", "/reservations/**").permitAll()
    .anyRequest().authenticated()
    .and()
  • 请求是否匹配“/”或“/login”或...?
    • 如果是,则允许任何人访问它并停止(不再使用更多规则)。
    • 如果请求不匹配,则继续。
  • 请求是否匹配任何请求?
    • 是的,所以如果请求与之前的规则不匹配,那么它将要求用户进行身份验证。

注意:antMatchers("/**") 更简洁地表示为 anyRequest()

Rob Winch 的回答几乎在所有情况下都是正确的,也是我在项目中采用的方法。我确实认为还值得注意的是,另一种可能的方法是执行以下操作:

public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/assets/**", "/index.html");
}

PLEASE NOTE that this is a separate method from the one in the examples you submitted earlier. That method has a parameter of type HttpSecurity while this one is of type WebSecurity.

此代码示例将查找所有匹配的请求并完全跳过 HTTP 安全过滤器。

因此,如果您想优化一些您知道需要 HttpSecurity 提供的功能中的零个的请求,那么这可能是一个很好的解决方案。这意味着如果您使用 csrf()requestCache()headers() 等功能,它们将不会应用于上述示例中的匹配请求(“/assets/**”、“/index.html")