如何使用Spring保护REST Web服务,尽管我未授权,但可以删除

时间:2019-05-09 17:46:21

标签: spring spring-security

我正在Spring中设置一个安全配置,我希望只有用户才能访问我在配置中编写的资源。例如,如果我没有写DELETE,我不希望任何用户都可以使用此请求, 除非我添加它,否则它是限制性最强的。我应该对我的代码进行哪些更改?

我写了下一个代码。 GETPOST可以,但是我可以删除,并且不添加此授权。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()                             
                .withUser("user")
                    .password(encoder().encode("passExample"))
                    .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .httpBasic()
                .and()
            .csrf()
                .disable()
            .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/**").hasRole("USER")
                .antMatchers(HttpMethod.POST, "/**").hasRole("USER")
                .and()
            .formLogin()
                .permitAll();

....

我希望,如果我向DELETE发出请求,则该应用程序不允许,因为我没有对其进行授权。

curl -X Delete locahost/servicio/1
{
    "timestamp": "2019-05-09T17:43:30.253+0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "Unauthorized",
    "path": "/service"
}

但是实际输出是状态204。服务器成功处理了请求。

2 个答案:

答案 0 :(得分:1)

您必须限制其他任何请求,请参见Spring Security Reference

  

6.4授权请求

     

我们的示例仅要求对用户进行身份验证,并且需要对应用程序中的每个URL进行身份验证。通过将多个子代添加到我们的http.authorizeRequests()方法中,我们可以为URL指定自定义要求。例如:

     
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()                                                                1
            .antMatchers("/resources/**", "/signup", "/about").permitAll()                  2
            .antMatchers("/admin/**").hasRole("ADMIN")                                      3
            .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")            4
            .anyRequest().authenticated()                                                   5
            .and()
        // ...
        .formLogin();
}
     
      
  1. http.authorizeRequests()方法有多个子级,每个匹配项都按声明顺序考虑。

  2.   
  3. 我们指定了任何用户都可以访问的多个URL模式。具体来说,如果URL以“ / resources /”开头,等于“ / signup”或等于“ / about”,则任何用户都可以访问请求。

  4.   
  5. 任何以“ / admin /”开头的URL都将限于角色为“ ROLE_ADMIN”的用户。您将注意到,由于我们正在调用hasRole方法,因此无需指定“ ROLE_”前缀。

  6.   
  7. 任何以“ / db /”开头的URL都要求用户同时具有“ ROLE_ADMIN”和“ ROLE_DBA”。您会注意到,由于我们使用的是hasRole表达式,因此无需指定“ ROLE_”前缀。

  8.   
  9. 任何尚未匹配的URL仅要求对用户进行身份验证

  10.   

并查看ExpressionUrlAuthorizationConfigurer#denyAll

  

denyAll

public ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry denyAll()
     

指定任何人都不允许使用URL。

您修改的代码:

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .httpBasic()
            .and()
        .csrf()
            .disable()
        .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/**").hasRole("USER")
            .antMatchers(HttpMethod.POST, "/**").hasRole("USER")
            .anyRequest().denyAll()
            .and()
        .formLogin()
            .permitAll();
}

答案 1 :(得分:0)

您配置的是对任何端点的任何GETPOST请求都应具有用户角色ROLE_USER,并允许所有其他类型的请求,例如(DELETE,{ {1}},HEAD等)。尝试拒绝所有其他类型的请求。

PUT或   .antMatchers("/**").denyAll();

请注意,这里的订单很重要。如果您在.anyRequest().denyAll();GET请求之前指定此选项,则所有请求都将被拒绝。