Skip to content

Commit

Permalink
Added oauth2 using keycloak for authentication and authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
tswlun002 committed Jul 18, 2024
1 parent ab06ae7 commit efa5495
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 0 deletions.
6 changes: 6 additions & 0 deletions config-server/src/main/resources/config/gatewayserver.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
server:
port: 8072
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: "http://keyClock:8080/realms/master/protocol/openid-connect/certs"
resilience4j.circuitbreaker:
configs:
default:
Expand Down
15 changes: 15 additions & 0 deletions docker-compose-servers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,21 @@ services:
- discoveryServerApp
networks:
- server_net

#KEYCLOCK CONTAINER
keyClock:
image: quay.io/keycloak/keycloak:23.0.6
container_name: keyClock
hostname: keyClock
ports:
- "7080:8080"
networks:
- server_net
environment:
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
command:
- start-dev
networks:
server_net:
external: true
Expand Down
17 changes: 17 additions & 0 deletions gateway-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,23 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.gatewayserver.config;

import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class KeycloakRoleConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
@Override
public Collection<GrantedAuthority> convert(Jwt source) {
Map<String, Set<String>> realmAccess = (Map<String, Set<String>>) source.getClaims().get("realm_access");
if(realmAccess==null||realmAccess.isEmpty()){
return new ArrayList<>();
}
return realmAccess.get("roles")
.stream().map(roleName->new SimpleGrantedAuthority("ROLE_"+roleName))
.collect(Collectors.toSet());

}

/*@Override
public <U> Converter<Jwt, U> andThen(Converter<? super Collection<GrantedAuthority>, ? extends U> after) {
return Converter.super.andThen(after);
}*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.gatewayserver.config;

public enum Roles {
CLIENT,
ADMIN
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.gatewayserver.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import reactor.core.publisher.Mono;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final String[] PATH_TO_AUTHENTICATE={"pdf-editor/users/**","pdf-editor/documents/**","pdf-editor/emails/**"};

@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity){
httpSecurity.
authorizeExchange(exchange->
exchange.pathMatchers(HttpMethod.GET).permitAll()
.pathMatchers(PATH_TO_AUTHENTICATE).hasAnyRole(Roles.ADMIN.name(),Roles.CLIENT.name())


)
.oauth2ResourceServer(oauth2Server->oauth2Server.jwt(jwtSpec ->
jwtSpec.jwtAuthenticationConverter(grantedAuth())));
httpSecurity.csrf(ServerHttpSecurity.CsrfSpec::disable);
return httpSecurity.build();
}

private Converter<Jwt,? extends Mono<? extends AbstractAuthenticationToken>> grantedAuth() {
var jwtConv= new JwtAuthenticationConverter();
jwtConv.setJwtGrantedAuthoritiesConverter(new KeycloakRoleConverter());
return new ReactiveJwtAuthenticationConverterAdapter(jwtConv);
}
}
7 changes: 7 additions & 0 deletions gateway-server/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ spring:
httpclient:
connect-timeout: 5000
response-timeout: 5s
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: "http://keyClock:8080/realms/master/protocol/openid-connect/certs"
main:
allow-bean-definition-overriding: true
management:
endpoints:
web:
Expand Down

0 comments on commit efa5495

Please sign in to comment.