SpringSecurity使用内存认证在http put方法中不要returns错误403
SpringSecurity using memory authentication don't returns error 403 in http put method
我在内存验证中使用 SpringSecurity 的 http“put”方法中没有收到错误 403。方法 returned 200 而它应该 return 403。
使用 http "post" 方法的相同代码可以正常工作。
注意例子:
网络安全配置:
@Configuration
public class WebSecutiryConfigurer extends WebSecurityConfigurerAdapter {
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Override
@Bean
protected UserDetailsService userDetailsService() {
return super.userDetailsService();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).withUser("11111111111")
.password(passwordEncoder().encode("minhasenha")).roles("Administrador").and().withUser("22222222222")
.password(passwordEncoder().encode("minhasenha")).roles("Consulta");
}
}
这是我的 ResourceServerConfigurerAdapter:
@Configuration
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/v1/cnaes").hasAnyRole("Administrador", "Alteracao", "Consulta")
.antMatchers(HttpMethod.POST, "/v1/cnaes").hasRole("Administrador")
.antMatchers(HttpMethod.DELETE, "/v1/cnaes").hasRole("Administrador")
.antMatchers(HttpMethod.PUT, "/v1/cnaes/delete").hasRole("Administrador")
.antMatchers(HttpMethod.PUT, "/v1/cnaes").hasRole("Administrador")
.and()
.anonymous().disable()
.exceptionHandling();
}
}
这是我测试的方法class:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class CnaeTeste {
@LocalServerPort
private int port;
private String urlGeracaoToken = "http://localhost:8088/oauth/token";
private String oauthTokenPerfilAdministrador;
private String oauthTokenPerfilConsulta;
@Before
public void setup() {
RestAssured.baseURI = "http://localhost:5555/mysystem/v1/cnaes";
}
@Before
public void autenticarPerfilAdministrador() {
Response response = RestAssured.given().auth().basic("usuario-bearer", "omissospj-pwd-bearer")
.formParam("scope", "intranet").formParam("username", "07068684718").formParam("password", "minhasenha")
.formParam("grant_type", "password").when().post(this.urlGeracaoToken);
this.oauthTokenPerfilAdministrador = response.jsonPath().get("access_token");
}
@Before
public void autenticarPerfilConsulta() {
Response response = RestAssured.given().auth().basic("usuario-bearer", "omissospj-pwd-bearer")
.formParam("scope", "intranet").formParam("username", "22222222222").formParam("password", "minhasenha")
.formParam("grant_type", "password").when().post(this.urlGeracaoToken);
this.oauthTokenPerfilConsulta = response.jsonPath().get("access_token");
}
@Test
public void falhaAtualizarQuandoUsuarioPerfilAlteracaoStatusCode403() throws Exception {
// insert
Cnae cnae = new Cnae(0L, "2222222", "CNAE de Teste - Criada - Perfil Administrador", false);
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(cnae);
Response responseInclusao = RestAssured.given()
.headers("Authorization", "Bearer " + this.oauthTokenPerfilAdministrador, "Content-Type",
ContentType.JSON, "Accept", ContentType.JSON)
.body(json).when().post();
Assertions.assertThat(responseInclusao.getStatusCode()).isEqualTo(201);
// update
String stringResponse = responseInclusao.getBody().asString();
JSONObject jsonObject = new JSONObject(stringResponse);
String idCadastrado = jsonObject.getString("id");
Long idAtualizado = Long.parseLong(idCadastrado);
cnae = new Cnae(idAtualizado, "2222222", "CNAE de Teste - Atualizada - Perfil Alteração", false);
ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
json = ow.writeValueAsString(cnae);
Response responseAlteracao = RestAssured.given().headers("Authorization",
"Bearer " + this.oauthTokenPerfilConsulta, "Content-Type", ContentType.JSON, "Accept", ContentType.JSON)
.body(json).when().put("/" + idCadastrado);
Assertions.assertThat(responseAlteracao.getStatusCode()).isEqualTo(403);
// delete
Response responseExcluir = RestAssured.given()
.headers("Authorization", "Bearer " + this.oauthTokenPerfilAdministrador, "Content-Type",
ContentType.JSON, "Accept", ContentType.JSON)
.when().delete("/" + idCadastrado).then().extract().response();
Assertions.assertThat(responseExcluir.getStatusCode()).isEqualTo(200);
}
}
我收到了 200 状态码,而我预计会收到 403:
Assertions.assertThat(responseAlteracao.getStatusCode()).isEqualTo(403);
有什么建议吗?
是删除也失败,还是只能放?
您的 put 指向 url
http://localhost:5555/mysystem/v1/cnaes/idCadastrado
但你只匹配 /v1/cnaes :
.antMatchers(HttpMethod.PUT, "/v1/cnaes").hasRole("Administrador")
也许您需要确保对其他请求进行身份验证:
.antMatchers(HttpMethod.PUT, "/v1/cnaes/**").authenticated()
或
.antMatchers(HttpMethod.PUT, "/v1/cnaes/**").hasRole("Administrador")
或
.anyRequest().hasRole("Administrador")
(添加所有其他 antMatchers 后放在最后)
如果你的控制器中没有映射到 /v1/cnaes/:id,它应该仍然会失败,但我在你提供的代码中看不到你的控制器入口点.我想如果入口点存在,并且安全级别为 @PreAuthorize("permitAll"),那么您将成功调用它。
我在内存验证中使用 SpringSecurity 的 http“put”方法中没有收到错误 403。方法 returned 200 而它应该 return 403。 使用 http "post" 方法的相同代码可以正常工作。 注意例子:
网络安全配置:
@Configuration
public class WebSecutiryConfigurer extends WebSecurityConfigurerAdapter {
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Override
@Bean
protected UserDetailsService userDetailsService() {
return super.userDetailsService();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).withUser("11111111111")
.password(passwordEncoder().encode("minhasenha")).roles("Administrador").and().withUser("22222222222")
.password(passwordEncoder().encode("minhasenha")).roles("Consulta");
}
}
这是我的 ResourceServerConfigurerAdapter:
@Configuration
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/v1/cnaes").hasAnyRole("Administrador", "Alteracao", "Consulta")
.antMatchers(HttpMethod.POST, "/v1/cnaes").hasRole("Administrador")
.antMatchers(HttpMethod.DELETE, "/v1/cnaes").hasRole("Administrador")
.antMatchers(HttpMethod.PUT, "/v1/cnaes/delete").hasRole("Administrador")
.antMatchers(HttpMethod.PUT, "/v1/cnaes").hasRole("Administrador")
.and()
.anonymous().disable()
.exceptionHandling();
}
}
这是我测试的方法class:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class CnaeTeste {
@LocalServerPort
private int port;
private String urlGeracaoToken = "http://localhost:8088/oauth/token";
private String oauthTokenPerfilAdministrador;
private String oauthTokenPerfilConsulta;
@Before
public void setup() {
RestAssured.baseURI = "http://localhost:5555/mysystem/v1/cnaes";
}
@Before
public void autenticarPerfilAdministrador() {
Response response = RestAssured.given().auth().basic("usuario-bearer", "omissospj-pwd-bearer")
.formParam("scope", "intranet").formParam("username", "07068684718").formParam("password", "minhasenha")
.formParam("grant_type", "password").when().post(this.urlGeracaoToken);
this.oauthTokenPerfilAdministrador = response.jsonPath().get("access_token");
}
@Before
public void autenticarPerfilConsulta() {
Response response = RestAssured.given().auth().basic("usuario-bearer", "omissospj-pwd-bearer")
.formParam("scope", "intranet").formParam("username", "22222222222").formParam("password", "minhasenha")
.formParam("grant_type", "password").when().post(this.urlGeracaoToken);
this.oauthTokenPerfilConsulta = response.jsonPath().get("access_token");
}
@Test
public void falhaAtualizarQuandoUsuarioPerfilAlteracaoStatusCode403() throws Exception {
// insert
Cnae cnae = new Cnae(0L, "2222222", "CNAE de Teste - Criada - Perfil Administrador", false);
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(cnae);
Response responseInclusao = RestAssured.given()
.headers("Authorization", "Bearer " + this.oauthTokenPerfilAdministrador, "Content-Type",
ContentType.JSON, "Accept", ContentType.JSON)
.body(json).when().post();
Assertions.assertThat(responseInclusao.getStatusCode()).isEqualTo(201);
// update
String stringResponse = responseInclusao.getBody().asString();
JSONObject jsonObject = new JSONObject(stringResponse);
String idCadastrado = jsonObject.getString("id");
Long idAtualizado = Long.parseLong(idCadastrado);
cnae = new Cnae(idAtualizado, "2222222", "CNAE de Teste - Atualizada - Perfil Alteração", false);
ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
json = ow.writeValueAsString(cnae);
Response responseAlteracao = RestAssured.given().headers("Authorization",
"Bearer " + this.oauthTokenPerfilConsulta, "Content-Type", ContentType.JSON, "Accept", ContentType.JSON)
.body(json).when().put("/" + idCadastrado);
Assertions.assertThat(responseAlteracao.getStatusCode()).isEqualTo(403);
// delete
Response responseExcluir = RestAssured.given()
.headers("Authorization", "Bearer " + this.oauthTokenPerfilAdministrador, "Content-Type",
ContentType.JSON, "Accept", ContentType.JSON)
.when().delete("/" + idCadastrado).then().extract().response();
Assertions.assertThat(responseExcluir.getStatusCode()).isEqualTo(200);
}
}
我收到了 200 状态码,而我预计会收到 403:
Assertions.assertThat(responseAlteracao.getStatusCode()).isEqualTo(403);
有什么建议吗?
是删除也失败,还是只能放?
您的 put 指向 url
http://localhost:5555/mysystem/v1/cnaes/idCadastrado
但你只匹配 /v1/cnaes :
.antMatchers(HttpMethod.PUT, "/v1/cnaes").hasRole("Administrador")
也许您需要确保对其他请求进行身份验证:
.antMatchers(HttpMethod.PUT, "/v1/cnaes/**").authenticated()
或
.antMatchers(HttpMethod.PUT, "/v1/cnaes/**").hasRole("Administrador")
或
.anyRequest().hasRole("Administrador")
(添加所有其他 antMatchers 后放在最后)
如果你的控制器中没有映射到 /v1/cnaes/:id,它应该仍然会失败,但我在你提供的代码中看不到你的控制器入口点.我想如果入口点存在,并且安全级别为 @PreAuthorize("permitAll"),那么您将成功调用它。