Skip to content

Commit 4b27594

Browse files
authored
Additional OIDC config (#562)
1 parent 493ee37 commit 4b27594

6 files changed

Lines changed: 70 additions & 34 deletions

File tree

README.md

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,27 +56,23 @@ Each variable can be overridden using environment variables.
5656
| `authentication.mode` | `none` | Supported modes are : `none`, `openidconnect` (must be configured) |
5757

5858
### Open id configuration (used when `authentication.mode`=`openidconnect`)
59-
You have to specify `oidc.issuer-uri`. `oidc.jwk-uri` is optional.
60-
Common used configurations :
61-
| Provider | `oidc.issuer-uri` | `oidc.jwk-uri` |
62-
|---|---|---|
63-
| Keycloak | `https://keycloak.example.com/auth/realms/REALMNAME` | |
64-
| Google | https://accounts.google.com | `https://www.googleapis.com/oauth2/v3/certs` |
65-
| Microsoft | `https://login.microsoftonline.com/TENANTID/v2.0` | |
59+
60+
The only two required parameters are `oidc.issuer-uri` and `oidc.clientID`. See below for more details.
6661

6762
Configurable properties :
6863
| Key | Default | Description |
6964
| -------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
70-
| `oidc.issuer-uri` | | Issuer URI, should be the same as the `iss` field of the tokens |
71-
| `oidc.skip-tls-verify` | `false` | Disable tls cert verification when retrieving keys from the IDP. Not intended for production. Consider mounting the proper `cacerts` instead of disabling the verification. |
72-
| `oidc.jwk-uri` | | JWK URI, useful when auto discovery is not available or when `iss` is not consistent across tokens (e.g [Google](https://stackoverflow.com/questions/38618826/can-i-get-a-consistent-iss-value-for-a-google-openidconnect-id-token)) |
73-
| `oidc.public-key` | | Public key used for validating incoming tokens. Don't provide this if you set `issuer-uri` or `jwk-uri` as it will be bootstrapped from that. This is useful if Onyxia-API has trouble connecting to your IDP (e.g self signed certificate). You can usually get this key directly by loading the issuer URI : (e.g `https://auth.example.com/realms/my-realm`) |
65+
| `oidc.issuer-uri` | | Issuer URI. Onyxia-API will use this URL to retrieve the public key for token validation. e.g for Keycloak : `https://keycloak.example.com/auth/realms/REALMNAME` |
7466
| `oidc.clientID` | | Client id to be used by Onyxia web application |
75-
| `oidc.audience` | | Optional : audience to validate. Must be the same as the token's `aud` field |
7667
| `oidc.username-claim` | `preferred_username` | Claim to be used as user id. Must conform to [RFC 1123](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names) |
7768
| `oidc.groups-claim` | `groups` | Claim to be used as list of user groups. |
7869
| `oidc.roles-claim` | `roles` | Claim to be used as list of user roles. |
70+
| `oidc.audience` | | Optional : audience to validate. Must be the same as the token's `aud` field |
71+
| `oidc.skip-tls-verify` | `false` | Disable tls cert verification when retrieving keys from the IDP. Not intended for production. Consider mounting the proper `cacerts` instead of disabling the verification. |
72+
| `oidc.public-key` | | Optional: If for some reason you don't want Onyxia-API to bootstrap configuration by requesting the `issuer-uri` then you can manually provide the public key used for validating incoming tokens. |
7973
| `oidc.extra-query-params` | | Optional : query params to be added by client. e.g : `prompt=consent&kc_idp_hint=google` |
74+
| `oidc.scope` | `openid profile` | Optional : Specifies the OIDC scopes to be requested by the Onyxia client. `"openid"` is always requested, regardless of this setting. |
75+
| `oidc.workaroundForGoogleClientSecret` | | For some reasons, Google OAuth requires providing a client secret even for public clients. ⚠️ Use this configuration only if using Google OAuth ! ⚠️ For all other providers you should not have client secret as the Onyxia client is public. Example client secret format: " `GOCSPX-_xxxxxxxxxxxxxxxxxxxxxxxxxxx` |
8076

8177
### Security configuration :
8278
| Key | Default | Description |

onyxia-api/src/main/java/fr/insee/onyxia/api/Application.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,11 @@ public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
3737
ConfigurableEnvironment environment = event.getEnvironment();
3838
MutablePropertySources propertySources = environment.getPropertySources();
3939
Map<String, Object> myMap = new HashMap<>();
40-
String oidcJwkUri = environment.getProperty("oidc.jwk-uri");
4140
String oidcIssuerUri = environment.getProperty("oidc.issuer-uri");
42-
LOGGER.info("oidc properties, jwk-uri: {}, issuer-uri: {}", oidcJwkUri, oidcIssuerUri);
4341

4442
if (StringUtils.isNotEmpty(oidcIssuerUri)) {
4543
myMap.put("spring.security.oauth2.resourceserver.jwt.issuer-uri", oidcIssuerUri);
4644
}
47-
if (StringUtils.isNotEmpty(oidcJwkUri)) {
48-
myMap.put("spring.security.oauth2.resourceserver.jwt.jwk-set-uri", oidcJwkUri);
49-
}
5045
propertySources.addFirst(new MapPropertySource("ALIASES", myMap));
5146
}
5247
}

onyxia-api/src/main/java/fr/insee/onyxia/api/controller/pub/ConfigurationController.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ public AppInfo configuration() {
5454
OIDCConfiguration.setIssuerURI(oidcConfiguration.getIssuerUri());
5555
OIDCConfiguration.setClientID(oidcConfiguration.getClientID());
5656
OIDCConfiguration.setExtraQueryParams(oidcConfiguration.getExtraQueryParams());
57+
OIDCConfiguration.setWorkaroundForGoogleClientSecret(
58+
oidcConfiguration.getWorkaroundForGoogleClientSecret());
59+
OIDCConfiguration.setScope(oidcConfiguration.getScope());
5760
appInfo.setOidcConfiguration(OIDCConfiguration);
5861
}
5962
return appInfo;

onyxia-api/src/main/java/fr/insee/onyxia/api/security/OIDCConfiguration.java

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,6 @@ public class OIDCConfiguration {
7979
@Value("${oidc.public-key}")
8080
private String publicKey;
8181

82-
@Value("${oidc.jwk-uri}")
83-
private String jwkUri;
84-
8582
@Value("${oidc.audience}")
8683
private String audience;
8784

@@ -94,6 +91,12 @@ public class OIDCConfiguration {
9491
@Value("${oidc.extra-query-params}")
9592
private String extraQueryParams;
9693

94+
@Value("${oidc.scope}")
95+
private String scope;
96+
97+
@Value("${oidc.workaroundForGoogleClientSecret}")
98+
private String workaroundForGoogleClientSecret;
99+
97100
private final HttpRequestUtils httpRequestUtils;
98101

99102
private static final Logger LOGGER = LoggerFactory.getLogger(OIDCConfiguration.class);
@@ -229,14 +232,6 @@ public void setIssuerUri(String issuerUri) {
229232
this.issuerUri = issuerUri;
230233
}
231234

232-
public String getJwkUri() {
233-
return jwkUri;
234-
}
235-
236-
public void setJwkUri(String jwkUri) {
237-
this.jwkUri = jwkUri;
238-
}
239-
240235
public String getAudience() {
241236
return audience;
242237
}
@@ -269,15 +264,44 @@ public void setExtraQueryParams(String extraQueryParams) {
269264
this.extraQueryParams = extraQueryParams;
270265
}
271266

267+
public boolean isSkipTlsVerify() {
268+
return skipTlsVerify;
269+
}
270+
271+
public void setSkipTlsVerify(boolean skipTlsVerify) {
272+
this.skipTlsVerify = skipTlsVerify;
273+
}
274+
275+
public String getRolesClaim() {
276+
return rolesClaim;
277+
}
278+
279+
public void setRolesClaim(String rolesClaim) {
280+
this.rolesClaim = rolesClaim;
281+
}
282+
283+
public String getScope() {
284+
return scope;
285+
}
286+
287+
public void setScope(String scope) {
288+
this.scope = scope;
289+
}
290+
291+
public void setWorkaroundForGoogleClientSecret(String workaroundForGoogleClientSecret) {
292+
this.workaroundForGoogleClientSecret = workaroundForGoogleClientSecret;
293+
}
294+
295+
public String getWorkaroundForGoogleClientSecret() {
296+
return workaroundForGoogleClientSecret;
297+
}
298+
272299
@Bean
273300
@ConditionalOnProperty(prefix = "oidc", name = "issuer-uri")
274301
NimbusJwtDecoder jwtDecoder() {
275302
NimbusJwtDecoder decoder = null;
276303
OAuth2TokenValidator<Jwt> validator = JwtValidators.createDefault();
277-
if (StringUtils.isNotEmpty(jwkUri)) {
278-
LOGGER.info("OIDC : using JWK URI {} to validate tokens", jwkUri);
279-
decoder = NimbusJwtDecoder.withJwkSetUri(jwkUri).build();
280-
} else if (StringUtils.isNotEmpty(publicKey)) {
304+
if (StringUtils.isNotEmpty(publicKey)) {
281305
LOGGER.info("OIDC : using public key {} to validate tokens", publicKey);
282306
try {
283307
byte[] decodedKey = Base64.getDecoder().decode(publicKey);

onyxia-api/src/main/resources/application.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ authentication.mode=none
33
# Open id connect authentication
44
oidc.issuer-uri=
55
oidc.skip-tls-verify=false
6-
oidc.jwk-uri=
76
oidc.public-key=
87
oidc.clientID=onyxia
98
oidc.audience=
109
oidc.username-claim=preferred_username
1110
oidc.groups-claim=groups
1211
oidc.roles-claim=roles
1312
oidc.extra-query-params=
13+
oidc.scope=openid profile
14+
oidc.workaroundForGoogleClientSecret=
1415
# Catalogs
1516
catalogs.refresh.ms=300000
1617
# Security

onyxia-model/src/main/java/fr/insee/onyxia/model/region/Region.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,9 @@ public static class OIDCConfiguration {
785785

786786
private String issuerURI;
787787
private String clientID;
788-
789788
private String extraQueryParams;
789+
private String scope;
790+
private String workaroundForGoogleClientSecret;
790791

791792
public String getIssuerURI() {
792793
return issuerURI;
@@ -811,6 +812,22 @@ public String getExtraQueryParams() {
811812
public void setExtraQueryParams(String extraQueryParams) {
812813
this.extraQueryParams = extraQueryParams;
813814
}
815+
816+
public String getWorkaroundForGoogleClientSecret() {
817+
return workaroundForGoogleClientSecret;
818+
}
819+
820+
public void setWorkaroundForGoogleClientSecret(String workaroundForGoogleClientSecret) {
821+
this.workaroundForGoogleClientSecret = workaroundForGoogleClientSecret;
822+
}
823+
824+
public String getScope() {
825+
return scope;
826+
}
827+
828+
public void setScope(String scope) {
829+
this.scope = scope;
830+
}
814831
}
815832

816833
public static class Expose {

0 commit comments

Comments
 (0)