【发布时间】:2020-03-04 20:50:45
【问题描述】:
我正在使用带有spring-security-oauth2-resource-server:5.2.0.RELEASE 的 Spring Boot 2.2.1。我想写一个集成测试来测试一下安全性是否可以。
我在我的应用程序中定义了这个WebSecurityConfigurerAdapter:
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtValidators;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private final OAuth2ResourceServerProperties properties;
private final SecuritySettings securitySettings;
public WebSecurityConfiguration(OAuth2ResourceServerProperties properties, SecuritySettings securitySettings) {
this.properties = properties;
this.securitySettings = securitySettings;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/**")
.authenticated()
.and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
}
@Bean
public JwtDecoder jwtDecoder() {
NimbusJwtDecoder result = NimbusJwtDecoder.withJwkSetUri(properties.getJwt().getJwkSetUri())
.build();
OAuth2TokenValidator<Jwt> validator = new DelegatingOAuth2TokenValidator<>(
JwtValidators.createDefault(),
new AudienceValidator(securitySettings.getApplicationId()));
result.setJwtValidator(validator);
return result;
}
private static class AudienceValidator implements OAuth2TokenValidator<Jwt> {
private final String applicationId;
public AudienceValidator(String applicationId) {
this.applicationId = applicationId;
}
@Override
public OAuth2TokenValidatorResult validate(Jwt token) {
if (token.getAudience().contains(applicationId)) {
return OAuth2TokenValidatorResult.success();
} else {
return OAuth2TokenValidatorResult.failure(
new OAuth2Error("invalid_token", "The audience is not as expected, got " + token.getAudience(),
null));
}
}
}
}
它有一个自定义验证器来检查令牌中的受众 (aud) 声明。
我目前有这个测试,它有效,但它根本不检查观众声明:
@WebMvcTest(UserController.class)
@EnableConfigurationProperties({SecuritySettings.class, OAuth2ResourceServerProperties.class})
@ActiveProfiles("controller-test")
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void testOwnUserDetails() throws Exception {
mockMvc.perform(get("/api/users/me")
.with(jwt(createJwtToken())))
.andExpect(status().isOk())
.andExpect(jsonPath("userId").value("AZURE-ID-OF-USER"))
.andExpect(jsonPath("name").value("John Doe"));
}
@Test
void testOwnUserDetailsWhenNotLoggedOn() throws Exception {
mockMvc.perform(get("/api/users/me"))
.andExpect(status().isUnauthorized());
}
@NotNull
private Jwt createJwtToken() {
String userId = "AZURE-ID-OF-USER";
String userName = "John Doe";
String applicationId = "AZURE-APP-ID";
return Jwt.withTokenValue("fake-token")
.header("typ", "JWT")
.header("alg", "none")
.claim("iss",
"https://b2ctestorg.b2clogin.com/80880907-bc3a-469a-82d1-b88ffad655df/v2.0/")
.claim("idp", "LocalAccount")
.claim("oid", userId)
.claim("scope", "user_impersonation")
.claim("name", userName)
.claim("azp", applicationId)
.claim("ver", "1.0")
.subject(userId)
.audience(Set.of(applicationId))
.build();
}
}
我还有一个 controller-test 配置文件的属性文件,其中包含应用程序 ID 和 jwt-set-uri:
security-settings.application-id=FAKE_ID
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://b2ctestorg.b2clogin.com/b2ctestorg.onmicrosoft.com/discovery/v2.0/keys?p=b2c_1_ropc_flow
可能因为 Jwt 是手动创建的,所以没有使用 JwtDecoder?如何确保在测试中调用了 JwtDecoder?
【问题讨论】:
标签: java spring spring-boot spring-security spring-test