如何使用Spring保护REST Web服务,删除是可能的,尽管我没有编写它



我正在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。服务器已成功处理请求。

您必须限制任何其他请求,请参阅 Spring 安全性参考:

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. 我们指定了任何用户都可以访问的多个 URL 模式。具体而言,如果 URL 以"/resources/"开头、等于"/signup"或等于"/about",则任何用户都可以访问请求。

  3. 任何以"/admin/"开头的 URL 都将仅限于具有"ROLE_ADMIN"角色的用户。您会注意到,由于我们正在调用 hasRole 方法,因此我们不需要指定"ROLE_"前缀。

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

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

并查看ExpressionUrlAuthorizationConfigurer#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();
}

您配置的是任何GET,对任何端点POST请求都应具有用户角色ROLE_USER并预先设置所有其他类型的请求,例如(DELETEHEADPUT等)。尝试拒绝所有其他类型的请求。

.antMatchers("/**").denyAll();.anyRequest().denyAll();

请注意,订单在这里很重要。如果在GETPOST请求之前指定此值,则所有请求都将被拒绝。

最新更新