Skip to content

Commit

Permalink
feat($Gateway): support ignored URL for WebFlux security
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnymillergh committed Dec 21, 2020
1 parent 2307c71 commit efb83ad
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,21 @@ public class CustomServerSecurityContextRepository implements ServerSecurityCont
private ReactiveAuthenticationManager authenticationManager;

@Override
public Mono save(ServerWebExchange swe, SecurityContext sc) {
public Mono<Void> save(ServerWebExchange swe, SecurityContext sc) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public Mono load(ServerWebExchange swe) {
public Mono<SecurityContext> load(ServerWebExchange swe) {
ServerHttpRequest request = swe.getRequest();
String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
String authToken = null;
if (authHeader != null && authHeader.startsWith(TOKEN_PREFIX)) {
authToken = authHeader.replace(TOKEN_PREFIX, "");
}else {
log.warn("couldn't find bearer string, will ignore the header.");
}
if (authToken != null) {
Authentication auth = new UsernamePasswordAuthenticationToken(authToken, authToken);
return this.authenticationManager.authenticate(auth).map((authentication) -> new SecurityContextImpl(authentication));
return this.authenticationManager.authenticate(auth).map(SecurityContextImpl::new);
} else {
return Mono.empty();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.jmsoftware.maf.gateway.universal.configuration;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
Expand All @@ -13,39 +14,40 @@
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
import reactor.core.publisher.Mono;

import java.util.ArrayList;

/**
* Description: WebFluxSecurityConfiguration, change description here.
*
* @author 钟俊(zhongjun), email: zhongjun@toguide.cn, date: 12/18/2020 3:23 PM
* @see
* <a href='https://docs.spring.io/spring-security/site/docs/5.3.6.RELEASE/reference/html5/#reactive-applications'>Spring Secirity Reference - Reactive Applications</a>
* @see
* <a href='https://www.devglan.com/spring-security/spring-security-webflux-jwt'>Securing Spring WebFlux Reactive APIs with JWT Auth</a>
* @see
* <a href='https://blog.csdn.net/tiancao222/article/details/104375924'>SpringCloud Gateway 整合 Spring Security Webflux 的关键点(痛点解析),及示例项目</a>
* @see <a href='https://docs.spring.io/spring-security/site/docs/5.3.6.RELEASE/reference/html5/#reactive-applications'>Spring Secirity Reference - Reactive Applications</a>
* @see <a href='https://www.devglan.com/spring-security/spring-security-webflux-jwt'>Securing Spring WebFlux Reactive APIs with JWT Auth</a>
* @see <a href='https://blog.csdn.net/tiancao222/article/details/104375924'>SpringCloud Gateway 整合 Spring Security Webflux 的关键点(痛点解析),及示例项目</a>
**/
@Slf4j
@Configuration
@EnableWebFluxSecurity
@RequiredArgsConstructor
public class WebFluxSecurityConfiguration {
private final CustomConfiguration customConfiguration;
private final ReactiveAuthenticationManager reactiveAuthenticationManager;
private final ServerSecurityContextRepository securityContextRepository;

@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
String[] patterns = new String[] {"/auth/**"};
return http.cors().disable()
.exceptionHandling()
.authenticationEntryPoint((swe, e) -> Mono.fromRunnable(() -> {
swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
})).accessDeniedHandler((swe, e) -> Mono.fromRunnable(() -> {
swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
})).and()
// TODO: response JSON
.authenticationEntryPoint((serverWebExchange, authenticationException) ->
Mono.fromRunnable(() -> serverWebExchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED)))
.accessDeniedHandler((serverWebExchange, accessDeniedException) ->
Mono.fromRunnable(() -> serverWebExchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN)))
.and()
.csrf().disable()
.authenticationManager(reactiveAuthenticationManager)
.securityContextRepository(securityContextRepository)
.authorizeExchange()
.pathMatchers(patterns).permitAll()
.pathMatchers(flattenIgnoredUrls()).permitAll()
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.anyExchange().authenticated()
.and()
Expand All @@ -56,4 +58,20 @@ SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

private String[] flattenIgnoredUrls() {
final var ignoredRequests = customConfiguration.getIgnoredRequest();
final var flattenIgnoredUrls = new ArrayList<String>();
flattenIgnoredUrls.addAll(ignoredRequests.getGet());
flattenIgnoredUrls.addAll(ignoredRequests.getPost());
flattenIgnoredUrls.addAll(ignoredRequests.getDelete());
flattenIgnoredUrls.addAll(ignoredRequests.getPut());
flattenIgnoredUrls.addAll(ignoredRequests.getHead());
flattenIgnoredUrls.addAll(ignoredRequests.getPatch());
flattenIgnoredUrls.addAll(ignoredRequests.getOptions());
flattenIgnoredUrls.addAll(ignoredRequests.getTrace());
flattenIgnoredUrls.addAll(ignoredRequests.getPattern());
log.info("Ignored URL list for WebFlux security: {}", flattenIgnoredUrls);
return flattenIgnoredUrls.toArray(new String[0]);
}
}
20 changes: 20 additions & 0 deletions gateway/src/main/resources/application-development-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,23 @@ custom:
configuration:
# Leave `allowed-application-list` empty
allowed-application-list:
super-user: "admin"
# Make `web-security-disabled` equal to true to disable web security. We suggest you do not turn off web security
# feature unless development environment.
web-security-disabled: false
# Disable web request information log
web-request-log-disabled: false
ignored-request:
post:
- "/authentication/**"
get:
- "/auth/check-username-uniqueness"
- "/auth/check-email-uniqueness"
- "/auth/validate-username/**"
- "/user/get-avatar"
- "/common/get-jwt"
pattern:
- "/actuator/**"
- "/druid/**"
- "/swagger-resources/**"
- "/v2/api-docs/**"

0 comments on commit efb83ad

Please sign in to comment.