-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #203 from skni-kod/issue-202
Poprawka wylogowania i oauth2
- Loading branch information
Showing
80 changed files
with
1,093 additions
and
818 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
services: | ||
kodemy-service-registry: | ||
ports: | ||
- "8761:8761" | ||
|
||
kodemy-api-gateway: | ||
ports: | ||
- "8080:8080" | ||
|
||
kodemy-auth: | ||
ports: | ||
- "8081:8080" | ||
|
||
kodemy-backend: | ||
ports: | ||
- "8082:8080" | ||
|
||
kodemy-notification: | ||
ports: | ||
- "8084:8080" | ||
|
||
kodemy-search: | ||
ports: | ||
- "8083:8080" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
...i-gateway/src/main/java/pl/sknikod/kodemygateway/configuration/SecurityConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package pl.sknikod.kodemygateway.configuration; | ||
|
||
import lombok.NonNull; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; | ||
import org.springframework.security.config.web.server.ServerHttpSecurity; | ||
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; | ||
import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizationRequestResolver; | ||
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationRequestResolver; | ||
import org.springframework.security.web.server.SecurityWebFilterChain; | ||
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler; | ||
import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; | ||
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; | ||
import pl.sknikod.kodemygateway.infrastructure.module.oauth2.OAuth2ReactiveAuthorizationManager; | ||
import reactor.core.publisher.Mono; | ||
|
||
import java.util.function.Function; | ||
|
||
import static org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizationRequestResolver.DEFAULT_REGISTRATION_ID_URI_VARIABLE_NAME; | ||
|
||
@Configuration | ||
@Slf4j | ||
@EnableWebFluxSecurity | ||
public class SecurityConfiguration { | ||
private static final Function<String, ServerWebExchangeMatcher> PATH_MATCHER_FUNCTION; | ||
|
||
static { | ||
PATH_MATCHER_FUNCTION = (endpoint) -> new PathPatternParserServerWebExchangeMatcher( | ||
endpoint + "/{" + DEFAULT_REGISTRATION_ID_URI_VARIABLE_NAME + "}" | ||
); | ||
} | ||
|
||
@Bean | ||
public SecurityWebFilterChain springSecurityFilterChain( | ||
ServerHttpSecurity http, | ||
ServerOAuth2AuthorizationRequestResolver authorizationRequestResolver, | ||
@Value("${app.security.oauth2.endpoint.callback}") String callbackEndpoint, | ||
OAuth2ReactiveAuthorizationManager reactiveAuthenticationManager | ||
) { | ||
http | ||
.authorizeExchange(auth -> auth.anyExchange().permitAll()) | ||
.oauth2Login(oauth2 -> oauth2 | ||
.authorizationRequestResolver(authorizationRequestResolver) | ||
.authenticationMatcher(callbackMatcher(callbackEndpoint)) | ||
.authenticationManager(reactiveAuthenticationManager) | ||
.authenticationSuccessHandler(authenticationSuccessHandler()) | ||
// TODO check if need change | ||
//.authenticationFailureHandler(authenticationFailureHandler()) | ||
); | ||
return http.build(); | ||
} | ||
|
||
private ServerAuthenticationSuccessHandler authenticationSuccessHandler() { | ||
return (webFilterExchange, authentication) -> webFilterExchange | ||
.getChain() | ||
.filter(webFilterExchange.getExchange()) | ||
.and(Mono.empty()); | ||
} | ||
|
||
/*private ServerAuthenticationFailureHandler authenticationFailureHandler() { | ||
return (webFilterExchange, exception) -> Mono.empty(); | ||
}*/ | ||
|
||
@Bean | ||
public ServerOAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver( | ||
ReactiveClientRegistrationRepository clientRegistrationRepository, | ||
@Value("${app.security.oauth2.endpoint.authorize}") String authorizeEndpoint | ||
) { | ||
return new DefaultServerOAuth2AuthorizationRequestResolver( | ||
clientRegistrationRepository, PATH_MATCHER_FUNCTION.apply(authorizeEndpoint) | ||
); | ||
} | ||
|
||
public ServerWebExchangeMatcher callbackMatcher(@NonNull String callbackEndpoint) { | ||
return PATH_MATCHER_FUNCTION.apply(callbackEndpoint); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
...knikod/kodemygateway/infrastructure/module/oauth2/OAuth2ReactiveAuthorizationManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package pl.sknikod.kodemygateway.infrastructure.module.oauth2; | ||
|
||
import org.springframework.security.authentication.ReactiveAuthenticationManager; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken; | ||
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationToken; | ||
import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||
import org.springframework.security.oauth2.core.OAuth2AuthorizationException; | ||
import org.springframework.security.oauth2.core.OAuth2Error; | ||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; | ||
import org.springframework.security.oauth2.core.user.DefaultOAuth2User; | ||
import org.springframework.stereotype.Component; | ||
import reactor.core.publisher.Mono; | ||
|
||
import java.util.Map; | ||
|
||
@Component | ||
public class OAuth2ReactiveAuthorizationManager implements ReactiveAuthenticationManager { | ||
@Override | ||
public Mono<Authentication> authenticate(Authentication authentication) { | ||
return Mono.defer(() -> { | ||
final var token = (OAuth2AuthorizationCodeAuthenticationToken) authentication; | ||
final var exchange = token.getAuthorizationExchange(); | ||
if (exchange.getAuthorizationResponse().statusError()) { | ||
return Mono.error(new OAuth2AuthorizationException(exchange.getAuthorizationResponse().getError())); | ||
} | ||
if (!isStateEqually(exchange)) { | ||
return Mono.error(new OAuth2AuthorizationException(new OAuth2Error("invalid_state_parameter"))); | ||
} | ||
return Mono.just(toOAuth2LoginAuthenticationToken(token)).onErrorMap(OAuth2AuthorizationException.class, | ||
(e) -> new OAuth2AuthenticationException(e.getError(), e.getError().toString(), e)); | ||
}); | ||
} | ||
|
||
private boolean isStateEqually(OAuth2AuthorizationExchange exchange) { | ||
return exchange.getAuthorizationRequest().getState() | ||
.equals(exchange.getAuthorizationResponse().getState()); | ||
} | ||
|
||
private Authentication toOAuth2LoginAuthenticationToken(OAuth2AuthorizationCodeAuthenticationToken token) { | ||
return new OAuth2LoginAuthenticationToken( | ||
token.getClientRegistration(), | ||
token.getAuthorizationExchange(), | ||
new DefaultOAuth2User(token.getAuthorities(), Map.of("name", token.getName()), "name"), | ||
token.getAuthorities(), | ||
new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, token.getAccessToken().getTokenValue(), | ||
token.getAccessToken().getIssuedAt(), token.getAccessToken().getExpiresAt()), | ||
token.getRefreshToken() | ||
); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
...way/src/main/java/pl/sknikod/kodemygateway/util/AddAuthorizationGatewayFilterFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package pl.sknikod.kodemygateway.util; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.logging.log4j.util.Strings; | ||
import org.springframework.cloud.gateway.filter.GatewayFilter; | ||
import org.springframework.cloud.gateway.filter.GatewayFilterChain; | ||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; | ||
import org.springframework.http.HttpCookie; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.server.reactive.ServerHttpRequest; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.server.ServerWebExchange; | ||
import reactor.core.publisher.Mono; | ||
|
||
import java.util.Optional; | ||
|
||
@Component | ||
@Slf4j | ||
public class AddAuthorizationGatewayFilterFactory | ||
extends AbstractGatewayFilterFactory<Object> { | ||
|
||
public AddAuthorizationGatewayFilterFactory() { | ||
super(Object.class); | ||
} | ||
|
||
@Override | ||
public GatewayFilter apply(Object config) { | ||
return new AddAuthorizationFilter(); | ||
} | ||
|
||
@RequiredArgsConstructor | ||
private static final class AddAuthorizationFilter implements GatewayFilter { | ||
private static final String ACCESS_TOKEN_COOKIE = "AUTH_CONTEXT"; | ||
|
||
@Override | ||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { | ||
return Optional.ofNullable(exchange.getRequest().getCookies().getFirst(ACCESS_TOKEN_COOKIE)) | ||
.map(HttpCookie::getValue) | ||
.filter(Strings::isNotEmpty) | ||
.map(token -> { | ||
log.info("Adding {} header", HttpHeaders.AUTHORIZATION); | ||
ServerHttpRequest modifiedRequest = exchange.getRequest().mutate() | ||
.headers(httpHeaders -> httpHeaders.setBearerAuth(token)) | ||
.header(HttpHeaders.COOKIE, (String) null) | ||
.build(); | ||
return chain.filter(exchange.mutate().request(modifiedRequest).build()); | ||
}) | ||
.orElseGet(() -> chain.filter(exchange)); | ||
} | ||
} | ||
} |
Oops, something went wrong.