Hallo,
wir nutzen Java 11 und die version 2.6.3 von spring-security-oauth2-autoconfigure. Wir haben eine locale und settings die wir auf unsere Test und Produktionsumgebung nutzen. Lokal möchten wir uns natürlich nicht authentifizieren, jedoch haben wir das Problem dass wir den principal an einer Stelle auslesen, wenn wir unsere API aufrufen und dort aber genau das Problem dann haben. Wenn ich unsere API local testen möchte, möchte ich über die Config einen Mock für den Principal setzen.
Die Config sieht wie folgt aus
Das ist ist ein call unserer Rest API den ich testen möchte
Hier holen wir den Principal aus der ServerWebExchange. Im darunter liegenden Service wird dann dieser Principal weiter verwendet und genau hier habe ich dann das Problem wo es fehlschlägt im lokalen Setting
Die einzige Möglichkeit die bei mir bisher funktioniert hat war genau in dieser Klasse einen Mock zu setzen
Dafür habe ich in der Config folgenden Mock erstellt, denn ich in der Implementierung dann injekte
Da dies hier wo ich den mock verwende aber Produktionscode ist, möchte ich das hier gerne anders lösen
über Profiling in der Config. Gibt es hier einen Weg?
wir nutzen Java 11 und die version 2.6.3 von spring-security-oauth2-autoconfigure. Wir haben eine locale und settings die wir auf unsere Test und Produktionsumgebung nutzen. Lokal möchten wir uns natürlich nicht authentifizieren, jedoch haben wir das Problem dass wir den principal an einer Stelle auslesen, wenn wir unsere API aufrufen und dort aber genau das Problem dann haben. Wenn ich unsere API local testen möchte, möchte ich über die Config einen Mock für den Principal setzen.
Die Config sieht wie folgt aus
Java:
@Profile({"!inhibit-security"})
@EnableReactiveMethodSecurity
class WebSecurityConfiguration {
}
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
@NonNull
private String issuerUri;
@Value("${spring.security.oauth2.resourceserver.jwt.audience}")
@NonNull
private String audience;
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
@NonNull
private String jwkSetUri;
@Bean
ReactiveJwtDecoder jwtDecoder() {
NimbusReactiveJwtDecoder jwtDecoder = new NimbusReactiveJwtDecoder(jwkSetUri);
OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(audience);
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
OAuth2TokenValidator<Jwt> chainValidator = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);
jwtDecoder.setJwtValidator(chainValidator);
return jwtDecoder;
}
@Profile({"!inhibit-security"})
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.csrf().disable()
.cors().and()
.authorizeExchange()
.pathMatchers("/").permitAll()
.pathMatchers("/swagger-ui/**").permitAll()
.pathMatchers("/openapi*").permitAll()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer().jwt();
return http.build();
}
@Bean
@ConditionalOnBean(CorsConfig.class)
CorsConfigurationSource corsFilter(CorsConfig corsConfig) {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(corsConfig.isAllowCredentials());
config.setAllowedOrigins(corsConfig.getOrigins());
config.setAllowedHeaders(corsConfig.getHeaders());
config.setAllowedMethods(corsConfig.getMethods());
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
// Local config
@Profile({"inhibit-security"})
@Bean
public SecurityWebFilterChain unsecuredWebFilterChain(ServerHttpSecurity http) {
http
.csrf().disable()
.cors().and()
.authorizeExchange()
.anyExchange().permitAll()
.and()
.oauth2ResourceServer().jwt();
return http.build();
}
Das ist ist ein call unserer Rest API den ich testen möchte
Java:
@Override
public Flux<StatusUpdate> reactiveSendEmailPost(
Mono<SendEmail> payload,
String xTraceId,
String xTestMode,
Mono<List<String>> attachmentIds,
Flux<FilePart> attachments,
ServerWebExchange exchange
) {
return super.acceptReactiveFlow(payload, xTraceId, xTestMode, attachmentIds, attachments, Channel.EMAIL, exchange.getPrincipal());
}
Hier holen wir den Principal aus der ServerWebExchange. Im darunter liegenden Service wird dann dieser Principal weiter verwendet und genau hier habe ich dann das Problem wo es fehlschlägt im lokalen Setting
Java:
.zipWith(principalMono)
Die einzige Möglichkeit die bei mir bisher funktioniert hat war genau in dieser Klasse einen Mock zu setzen
Java:
.zipWith(mockPrincipal == null ? principalMono: Mono.just(mockPrincipal))
Dafür habe ich in der Config folgenden Mock erstellt, denn ich in der Implementierung dann injekte
Java:
@Profile({"inhibit-security"})
@Bean
public Principal mockPrincipal() {
return new Authentication() {
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getPrincipal() {
return null;
}
@Override
public boolean isAuthenticated() {
return false;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
}
@Override
public String getName() {
return null;
}
};
}
Da dies hier wo ich den mock verwende aber Produktionscode ist, möchte ich das hier gerne anders lösen
Java:
.zipWith(mockPrincipal == null ? principalMono: Mono.just(mockPrincipal))
über Profiling in der Config. Gibt es hier einen Weg?