Skip to content

Commit

Permalink
#12 authentication
Browse files Browse the repository at this point in the history
- keycloak connected with API Gateway
- keycloak JWT Tokens passed to services
  • Loading branch information
maciejgz committed Oct 7, 2023
1 parent bc701d1 commit bfb9566
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 3 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,10 @@ kubectl apply -f ms-stock-service/k8s

Users are stored in Keycloak. <br />
Predefined users: </br>
Admin:
Keycloak admin users:
- admin/admin

</br>Admin role users:

- admin_user_1/admin_user_1 role `admin`
- admin_user_2/admin_user_2 role `admin`
Expand Down
5 changes: 4 additions & 1 deletion ms-api-gateway/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-micrometer</artifactId>
Expand All @@ -38,7 +42,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class ProductKeyResolver implements KeyResolver {

@Override
public Mono<String> resolve(ServerWebExchange exchange) {
log.info("Request from {}", Objects.requireNonNull(exchange.getRequest().getLocalAddress().getHostName()));
log.debug("Request from {}", Objects.requireNonNull(exchange.getRequest().getLocalAddress().getHostName()));
return Mono.just(Objects.requireNonNull(exchange.getRequest().getLocalAddress().getHostName()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package pl.mg.ms.gw.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher;

@Configuration
@EnableWebFluxSecurity
public class WebSecurityConfiguration {

@Order(1)
@Bean
SecurityWebFilterChain actuatorHttpSecurity(ServerHttpSecurity http) {
http
.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/actuator/**"))
.authorizeExchange((exchanges) -> exchanges
.anyExchange().permitAll()
);
return http.build();
}

@Bean
SecurityWebFilterChain apiHttpSecurity(ServerHttpSecurity http) {
http
.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/api/**"))
.authorizeExchange((exchanges) -> exchanges
.anyExchange().authenticated()
)
.oauth2ResourceServer(oAuth2ResourceServerSpec -> oAuth2ResourceServerSpec
.jwt(Customizer.withDefaults()))
.csrf(Customizer.withDefaults());
return http.build();
}

}
5 changes: 5 additions & 0 deletions ms-api-gateway/src/main/resources/application-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ management:

## API Gateway routes
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: http://localhost:8082/realms/ms/protocol/openid-connect/certs
cloud:
gateway:
routes:
Expand Down
12 changes: 12 additions & 0 deletions ms-api-gateway/src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ management:

## API Gateway routes
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: http://localhost:8082/realms/ms/protocol/openid-connect/certs
cloud:
gateway:
routes:
Expand Down Expand Up @@ -89,3 +94,10 @@ spring:
args:
name: cms-api-group-1-cb
fallbackUri: forward:/fallback/cms

logging:
level:
root: INFO
pl.mg: DEBUG
org.springframework.cloud.gateway: DEBUG
org.springframework.security: TRACE
4 changes: 4 additions & 0 deletions ms-cms-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<!-- kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package pl.mg.search.cms.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
@Configuration
public class SecurityConfig {

@Order(1)
@Bean
public SecurityFilterChain actuatorHttpSecurity(HttpSecurity http) throws Exception {
http
.securityMatcher(request -> request.getServletPath().startsWith("/actuator/"))
.authorizeHttpRequests((requests) -> requests
.anyRequest().permitAll()
);
return http.build();
}

@Bean
public SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
http
.securityMatcher(request -> request.getServletPath().startsWith("/api/"))
.authorizeHttpRequests((exchanges) -> exchanges
.anyRequest().authenticated()
)
.oauth2ResourceServer(oAuth2ResourceServerSpec -> oAuth2ResourceServerSpec
.jwt(Customizer.withDefaults()))
.csrf(Customizer.withDefaults());
return http.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -40,7 +43,16 @@ public ResponseEntity<Page<CmsProduct>> filter(
HttpServletRequest request,
Pageable page,
@RequestParam(name = "q") String query

) {

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = authentication.getName();
log.debug("user authenticated as: {}", username);
org.springframework.security.oauth2.jwt.Jwt jwt = (Jwt) authentication.getPrincipal();

log.debug(jwt.getSubject());

log.debug("Request: {}", request.getRequestURI());
Page<CmsProduct> products = repository.findByTitleContainingIgnoreCaseOrDescriptionContainingIgnoreCase(query, query, page);
return ResponseEntity.ok(products);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8082/realms/ms/protocol/openid-connect/certs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8082/realms/ms/protocol/openid-connect/certs
4 changes: 4 additions & 0 deletions ms-stock-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package pl.mg.search.stock.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
@Configuration
public class SecurityConfig {
@Order(1)
@Bean
public SecurityFilterChain actuatorHttpSecurity(HttpSecurity http) throws Exception {
http
.securityMatcher(request -> request.getServletPath().startsWith("/actuator/"))
.authorizeHttpRequests((requests) -> requests
.anyRequest().permitAll()
);
return http.build();
}

@Bean
public SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
http
.securityMatcher(request -> request.getServletPath().startsWith("/api/"))
.authorizeHttpRequests((exchanges) -> exchanges
.anyRequest().authenticated()
)
.oauth2ResourceServer(oAuth2ResourceServerSpec -> oAuth2ResourceServerSpec
.jwt(Customizer.withDefaults()))
.csrf(Customizer.withDefaults());
return http.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8082/realms/ms/protocol/openid-connect/certs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:8082/realms/ms/protocol/openid-connect/certs

0 comments on commit bfb9566

Please sign in to comment.