Skip to content

Commit

Permalink
Oauth on internal endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Max Zollbrecht committed Apr 24, 2024
1 parent f1974a2 commit edbd43c
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
@Slf4j
@CrossOrigin
@RestController
@SecurityRequirement(name = "BasicAuth")
@SecurityRequirement(name = "InternalLogin")
@RequestMapping(path = "/internal/", produces = "application/json")
public class InternalApiController {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
@Slf4j
@CrossOrigin
@RestController
@SecurityRequirement(name = "OAUTH2")
@SecurityRequirement(name = "ApiClient")
@RequestMapping(path = "/kitaApp/v1", produces = "application/json")
public class KitaAppApiController {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
*/
package de.muenchen.rbs.kitafindereai.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.SpringOpaqueTokenIntrospector;
import org.springframework.security.web.SecurityFilterChain;

import de.muenchen.rbs.kitafindereai.api.InternalApiController;
Expand All @@ -42,28 +42,48 @@ public class SecurityConfiguration {
@Bean
@Order(1)
@Profile("!no-security")
public SecurityFilterChain internalApiSecurityFilterChain(HttpSecurity http) throws Exception {
public SecurityFilterChain internalApiSecurityFilterChain(HttpSecurity http,
@Qualifier("internalTokenIntrospector") OpaqueTokenIntrospector introspector) throws Exception {
http.securityMatcher("/internal/**")
.authorizeHttpRequests(requests -> requests.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults());
.oauth2ResourceServer((oauth2) -> oauth2
.opaqueToken(config -> config.introspector(introspector)));
http.cors(cors -> cors.disable()).csrf(csrf -> csrf.disable());
return http.build();
}

@Primary
@Bean("internalTokenIntrospector")
public OpaqueTokenIntrospector internalTokenIntrospector(
@Value("${app.security.introspection-url}") String introspectionUri,
@Value("${app.security.internal.client-id}") String clientId,
@Value("${app.security.internal.client-secret}") String clientSecret) {
return new SpringOpaqueTokenIntrospector(introspectionUri, clientId, clientSecret);
}

/** Security for {@link KitaAppApiController} */
@Bean
@Order(2)
@Profile("!no-security")
public SecurityFilterChain kitaAppApiSecurityFilterChain(HttpSecurity http) throws Exception {
public SecurityFilterChain kitaAppApiSecurityFilterChain(HttpSecurity http,
@Qualifier("apiTokenIntrospector") OpaqueTokenIntrospector introspector) throws Exception {
http.securityMatcher("/kitaApp/**")
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated())
.oauth2ResourceServer((oauth2) -> oauth2
.opaqueToken(Customizer.withDefaults()));
.opaqueToken(config -> config.introspector(introspector)));
http.cors(cors -> cors.disable()).csrf(csrf -> csrf.disable());
return http.build();
}

@Bean("apiTokenIntrospector")
public OpaqueTokenIntrospector apiTokenIntrospector(
@Value("${app.security.introspection-url}") String introspectionUri,
@Value("${app.security.api.client-id}") String clientId,
@Value("${app.security.api.client-secret}") String clientSecret) {
return new SpringOpaqueTokenIntrospector(introspectionUri, clientId, clientSecret);
}

/**
* Security for remaining endpoints.
* Excluding Swagger UI and spring actuators.
Expand All @@ -83,22 +103,6 @@ public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws
return http.build();
}

/**
* UserDetailsService for BasicAuth
*
* @param user User for BasicAuth
* @param password Password for BasicAuth
* @return UserDetailsService for BasicAuth
*/
@Bean
@Profile("!no-security")
public UserDetailsService userDetailsService(@Value("${app.internalApi.authentication.user}") String user,
@Value("${app.internalApi.authentication.password}") String password) {
UserDetails userDetails = User.withDefaultPasswordEncoder().username(user).password(password).build();

return new InMemoryUserDetailsManager(userDetails);
}

/** Security-config for profile 'no-security' */
@Bean
@Profile("no-security")
Expand All @@ -112,8 +116,8 @@ public SecurityFilterChain noSecurityFilterChain(HttpSecurity http)

/** Swagger-API config for security */
@Configuration
@SecurityScheme(name = "OAUTH2", type = SecuritySchemeType.OAUTH2, flows = @OAuthFlows(clientCredentials = @OAuthFlow(tokenUrl = "${app.security.token-url}")))
@SecurityScheme(name = "BasicAuth", type = SecuritySchemeType.HTTP, scheme = "basic")
@SecurityScheme(name = "ApiClient", type = SecuritySchemeType.OAUTH2, flows = @OAuthFlows(clientCredentials = @OAuthFlow(tokenUrl = "${app.security.token-url}")))
@SecurityScheme(name = "InternalLogin", type = SecuritySchemeType.OAUTH2, flows = @OAuthFlows(password = @OAuthFlow(tokenUrl = "${app.security.token-url}", authorizationUrl = "${app.security.authorization-url}")))
public class SpringdocConfig {
}

Expand Down
22 changes: 11 additions & 11 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ app:
security:
sso-base-url: https://ssodev.muenchen.de
realm: A23
client-id: instikom-kf-schnittstelle
# app.security.client-secret: required for oauth authentication to work.
# Add in programm arguments or environment
introspection-url: ${app.security.sso-base-url}/auth/realms/${app.security.realm}/protocol/openid-connect/token/introspect
authorization-url: ${app.security.sso-base-url}/auth/realms/${app.security.realm}/protocol/openid-connect/auth
token-url: ${app.security.sso-base-url}/auth/realms/${app.security.realm}/protocol/openid-connect/token
api:
client-id: instikom-kf-schnittstelle
# app.security.client-secret: required for oauth authentication to work.
# Add in programm arguments or environment
internal:
client-id: kf-app-eai-internal
# app.security.client-secret: required for oauth authentication to work.
# Add in programm arguments or environment
passwordEncoder:
# Encryption properties. Overwrite in non-dev-environments!
encryptor:
Expand All @@ -22,20 +29,13 @@ app:
spring:
application:
name: kita-finder-eai
security:
oauth2:
resourceserver:
opaquetoken:
introspection-uri: ${app.security.sso-base-url}/auth/realms/${app.security.realm}/protocol/openid-connect/token/introspect
client-id: ${app.security.client-id}
client-secret: ${app.security.client-secret}

# swagger-ui configuration
springdoc:
swagger-ui:
path: /swagger-ui.html
oauth:
clientId: ${app.security.client-id}
clientId: ${app.security.api.client-id}
realm: ${app.security.realm}
appName: ${spring.application.name}
default-produces-media-type: application/json
Expand Down

0 comments on commit edbd43c

Please sign in to comment.