使用.antMatchers()

时间:2019-01-30 16:57:22

标签: java spring rest security cors

我正在为Spring Boot应用程序设计REST API,但是我在设计时遇到了问题。我想以前缀/project_name/v1/启动所有REST端点。

我有数百个端点经过身份验证保护,只有一对端点无需身份验证即可访问。

这是当前状态

Method | Endpoint                       | Secure
------------------------------------------------------------------
POST   | /project_name/activate         | accessible to everybody
GET    | /project_name/activate/{id}    | accessible to everybody
GET    | /project_name/v1/getAllUsers/  | protected by token
GET    | /project_name/v1/getUser/{id}  | protected by token
POST   | /project_name/v1/createUser/   | protected by token
...    | /project_name/v1/...           | protected by token

这是所需状态

Method | Endpoint                       | Secure
------------------------------------------------------------------
POST   | /project_name/v1/activate      | accessible to everybody
GET    | /project_name/v1/activate/{id} | accessible to everybody
GET    | /project_name/v1/getAllUsers/  | protected by token
GET    | /project_name/v1/getUser/{id}  | protected by token
POST   | /project_name/v1/createUser/   | protected by token
...    | /project_name/v1/...           | protected by token

我已经厌倦了几种方法。例如:

  • 在我理解顺序很重要的同时,我尝试使用.antMatchers()的顺序。这种方法无法使用,因为如果首先在与.authenticated()相同的路径上声明任何内容,则其他任何内容都不能是.permitAll();如果反向-.permitAll()使不需要的所有内容都成为.authenticated()
  • 我已经在.antMatchers()中列出了所有具有适当授权的特定端点。再次,顺序可能很重要,并陷入了与上一个相同的问题。

我尝试过的一切都没有。

是否有一种方法可以使用.permitAll()和.authenticated()在一个公共路径下拥有未经身份验证和受保护的端点?

当前解决方案有效。这是ResourceServerConfiguration类:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@SuppressWarnings("DesignForExtension")
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    private final TokenStore tokenStore;

    @Autowired
    public ResourceServerConfiguration(final TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }

    @Override
    public final void configure(final HttpSecurity http) {
        try {
            http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers("/project_name/activate/v1/**").permitAll()
                .antMatchers("/project_name/v1/**").authenticated();
            http.servletApi().rolePrefix("");
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public void configure(final ResourceServerSecurityConfigurer config) {
        config.tokenStore(this.tokenStore);
    }
}

2 个答案:

答案 0 :(得分:0)

匹配器按照它们出现的顺序进行考虑,如果您想保护BUT 2端点的所有内容,可能需要类似以下内容:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@SuppressWarnings("DesignForExtension")
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    private final TokenStore tokenStore;

    @Autowired
    public ResourceServerConfiguration(final TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }

    @Override
    public final void configure(final HttpSecurity http) {
        try {
            http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers("/project_name/v1/**").authenticated();
                .antMatchers("/project_name/v1/activate/**").permitAll()
            http.servletApi().rolePrefix("");
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public void configure(final ResourceServerSecurityConfigurer config) {
        config.tokenStore(this.tokenStore);
    }
}

通过这种方式,Spring Security将只覆盖具有匿名访问权限的v1 / activate / **路径,并保持v1 / **中包含的其他路径的安全。

答案 1 :(得分:0)

基于rafura的建议,我试图提出解决方案。扭曲按端点的顺序排列。以下解决方案有效:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@SuppressWarnings("DesignForExtension")
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    private final TokenStore tokenStore;

    @Autowired
    public ResourceServerConfiguration(final TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }

    @Override
    public final void configure(final HttpSecurity http) {
        try {
            http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers("/project_name/v1/activate/**").permitAll()
                .antMatchers("/project_name/v1/**").authenticated();
            http.servletApi().rolePrefix("");
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public void configure(final ResourceServerSecurityConfigurer config) {
        config.tokenStore(this.tokenStore);
    }
}

我猜想Spring首先使用适当的路径映射特定端点。然后使用其余的授权级别填充将找到的其余端点。

请注意rafura答案: 倒序不起作用。可能是因为某些路径下的所有内容都获得了授权,并且当Spring找到列出的特定端点时,已经将其标记为必需的授权。如上面的答案所述,反向顺序有效。

相关问题