在使用凭据流时,如何使用OAuth2编写IntetGration测试Spring Web客户端(Spring MVC)
我有一个 oauth 2客户端,它实际上与另一个用作授权服务器的微服务(auth-server)交互。 我有一个端点(使用Spring MVC)。 的注释
@PreAuthorize("has Scope(T(.........).
@Configuration
public class AuthWebClientConfiguration {
@Bean
public OAuth2AuthorizedClientManager authorizedManager(
ClientRegistrationRepository client,
OAuth2AuthorizedClientRepository authorizedClient
) {
OAuth2AuthorizedClientProvider authorizedProvider =
OAuth2AuthorizedClientProviderBuilder
.builder()
.authorizationCode()
.refreshToken()
.clientCredentials()
.build();
DefaultOAuth2AuthorizedClientManager authorizedManager =
new DefaultOAuth2AuthorizedClientManager(
client,
authorizedClient
);
authorizedClientManager.setAuthorizedClientProvider(authorizedProvider);
return authorizedManager;
}
@Bean
public ServletOAuth2AuthorizedClientExchangeFilterFunction oauthClient(OAuth2AuthorizedClientManager authorizedManager) {
return new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedManager);
}
}
@Service
@RequiredArgsConstructor
public class AuthClientManager {
public static final String SERVICE_ID = "my-service";
private final OAuth2AuthorizedClientManager oAuth2Manager;
private final ServletOAuth2AuthorizedClientExchangeFilterFunction
filterFunction;
private final WebClient webClient;
private WebClient client;
public WebClient getClient() {
return Optional.ofNullable(client)
.orElseGet(() -> {
OAuth2AuthorizeRequest authorizeRequest =
OAuth2AuthorizeRequest.withClientRegistrationId(SERVICE_ID)
.principal(SERVICE_ID)
.build();
client = webClient
.mutate()
.filter(
(request, next) -> next
.exchange(
ClientRequest.from(request)
.attributes(
oauth2AuthorizedClient(
oAuth2Manager.authorize(authorizeRequest)
)
).build()
)
)
.apply(filterFunction.oauth2Configuration())
.build();
return client;
});
}
}
- 端点
@RequestMapping("email")
public interface RestController {
@PreAuthorize("hasScope(T(......MESSAGE_SEND)")
@PostMapping("v1/message")
ResponseEntity<Void> send(@Valid @RequestBody Dto dto);
}
- 实现
@RestController
@RequiredArgsConstructor
@Slf4j
public class RestControllerImpl implements RestController {
@Override
public ResponseEntity<Void> send(Dto dto) {
return new ResponseEntity<>(HttpStatus.OK);
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
@RequiredArgsConstructor
public class SecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new ScopeAwareExpressionHandler();
}
@Bean
@Order(0)
SecurityFilterChain apiFilterChain(
HttpSecurity http,
@Value("${spring.security.oauth2.client.provider-uri}") String hostname
) throws Exception {
return http
.cors()
.configurationSource(request ->
new CorsConfiguration()
.applyPermitDefaultValues()
)
.and()
.csrf().disable()
.requestMatchers(
requestMatcherConfigurer -> requestMatcherConfigurer.antMatchers("/**")
)
.authorizeRequests(authorizeRequestsCustomized -> authorizeRequestsCustomized
.antMatchers(
"/swagger-ui/**"
)
.permitAll()
.anyRequest()
.authenticated()
)
.oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer ->
httpSecurityOAuth2ResourceServerConfigurer
.jwt()
.jwkSetUri(hostname + "/oauth2/jwks")
)
.build();
}
}
- 它具有端点应用程序
spring:
security:
oauth2:
client:
registration:
my-service: # my-service
provider: spring
client-id: 1
client-secret:1
authorization-grant-type: client_credentials
scope: message.send
client-name: 1
provider:
spring:
issuer-uri:locachost....
user-info-uri: locachost..../api/v1/users/me
user-name-attribute: id
。YAMLA希望为此端点编写集成测试,以验证 oauth2 client for cordentials flow flow 是否正确配置。好吧,一方面是我终点的工作。
我该怎么办?
我没有找到任何适合我任务的例子。
有人可以分享有关此案的知识吗?
I have an Oauth 2 client that actually interacts with another microservice that acts as an authorization server (auth-server).
I have an endpoint (use spring mvc). It has the annotation
@PreAuthorize("has Scope(T(.........).
@Configuration
public class AuthWebClientConfiguration {
@Bean
public OAuth2AuthorizedClientManager authorizedManager(
ClientRegistrationRepository client,
OAuth2AuthorizedClientRepository authorizedClient
) {
OAuth2AuthorizedClientProvider authorizedProvider =
OAuth2AuthorizedClientProviderBuilder
.builder()
.authorizationCode()
.refreshToken()
.clientCredentials()
.build();
DefaultOAuth2AuthorizedClientManager authorizedManager =
new DefaultOAuth2AuthorizedClientManager(
client,
authorizedClient
);
authorizedClientManager.setAuthorizedClientProvider(authorizedProvider);
return authorizedManager;
}
@Bean
public ServletOAuth2AuthorizedClientExchangeFilterFunction oauthClient(OAuth2AuthorizedClientManager authorizedManager) {
return new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedManager);
}
}
@Service
@RequiredArgsConstructor
public class AuthClientManager {
public static final String SERVICE_ID = "my-service";
private final OAuth2AuthorizedClientManager oAuth2Manager;
private final ServletOAuth2AuthorizedClientExchangeFilterFunction
filterFunction;
private final WebClient webClient;
private WebClient client;
public WebClient getClient() {
return Optional.ofNullable(client)
.orElseGet(() -> {
OAuth2AuthorizeRequest authorizeRequest =
OAuth2AuthorizeRequest.withClientRegistrationId(SERVICE_ID)
.principal(SERVICE_ID)
.build();
client = webClient
.mutate()
.filter(
(request, next) -> next
.exchange(
ClientRequest.from(request)
.attributes(
oauth2AuthorizedClient(
oAuth2Manager.authorize(authorizeRequest)
)
).build()
)
)
.apply(filterFunction.oauth2Configuration())
.build();
return client;
});
}
}
- endpoint
@RequestMapping("email")
public interface RestController {
@PreAuthorize("hasScope(T(......MESSAGE_SEND)")
@PostMapping("v1/message")
ResponseEntity<Void> send(@Valid @RequestBody Dto dto);
}
- implementation of endpoint
@RestController
@RequiredArgsConstructor
@Slf4j
public class RestControllerImpl implements RestController {
@Override
public ResponseEntity<Void> send(Dto dto) {
return new ResponseEntity<>(HttpStatus.OK);
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
@RequiredArgsConstructor
public class SecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new ScopeAwareExpressionHandler();
}
@Bean
@Order(0)
SecurityFilterChain apiFilterChain(
HttpSecurity http,
@Value("${spring.security.oauth2.client.provider-uri}") String hostname
) throws Exception {
return http
.cors()
.configurationSource(request ->
new CorsConfiguration()
.applyPermitDefaultValues()
)
.and()
.csrf().disable()
.requestMatchers(
requestMatcherConfigurer -> requestMatcherConfigurer.antMatchers("/**")
)
.authorizeRequests(authorizeRequestsCustomized -> authorizeRequestsCustomized
.antMatchers(
"/swagger-ui/**"
)
.permitAll()
.anyRequest()
.authenticated()
)
.oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer ->
httpSecurityOAuth2ResourceServerConfigurer
.jwt()
.jwkSetUri(hostname + "/oauth2/jwks")
)
.build();
}
}
- application.yaml
spring:
security:
oauth2:
client:
registration:
my-service: # my-service
provider: spring
client-id: 1
client-secret:1
authorization-grant-type: client_credentials
scope: message.send
client-name: 1
provider:
spring:
issuer-uri:locachost....
user-info-uri: locachost..../api/v1/users/me
user-name-attribute: id
A would like to write an integration test for this endpoint to verify that the Oauth2 client for Credentials flow is configured correctly. well, for one thing, the work of my endpoint.
How could I do that ?
I have not found any examples suitable for my task.
Could someone share knowledge about this case.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果要编写集成测试:
我宁愿使用@webmvctest或@webfluxtest bfluxtest编写单元测试,并使用spring-security-test或@withmockjwtauth从 https://github.com/ch4mpy/spring-addons
If you want to write integration test:
I'd rather write unit tests with @WebmvcTest or @WebfluxTest bfluxTest and configure test security context with jwt() MockMvc post processor (or Word bTestClient mutator) from spring-security-test or @WithMockJwtAuth from https://github.com/ch4mpy/spring-addons