我正在使用带有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
也许不使用JwtDecoder,因为Jwt是手动创建的吗?如何确保在测试中调用了JwtDecoder?