Implemented OpenId configuration.
Change-Id: I4e41a6072797742266d86c1709ad8941ae2c17f1
diff --git a/full/Changes b/full/Changes
index a8c1c2f..3af7de8 100644
--- a/full/Changes
+++ b/full/Changes
@@ -1,5 +1,5 @@
version 0.60.4
-26/06/2018
+27/06/2018
- implemented OAuth2 authorization code request with OpenID Authentication (margaretha)
- enabled OAuth2 authorization without OpenID authentication using Nimbus library (margaretha)
- implemented response handler for OpenID authentication errors in authorization requests (margaretha)
@@ -9,6 +9,7 @@
- implemented OpenID token service for authorization code flow (margaretha)
- implemented signed OpenID token with default algorithm RSA256 (margaretha)
- added JSON Web Key (JWK) set web-controller listing kustvakt public keys (margaretha)
+ - implemented OpenId configuration (margaretha)
version 0.60.3
06/06/2018
diff --git a/full/pom.xml b/full/pom.xml
index 9ae96d9..5b4a093 100644
--- a/full/pom.xml
+++ b/full/pom.xml
@@ -32,15 +32,9 @@
<testResources>
<testResource>
<directory>src/test/resources</directory>
- <!-- <filtering>true</filtering>
- <includes>
- <include>**/*.key</include>
- <include>**/*.token</include>
- <include>**/*.xml</include>
- <include>**/*.conf</include>
- <include>**/*.info</include>
- <include>**/*.properties</include>
- </includes> -->
+ <!-- <filtering>true</filtering> <includes> <include>**/*.key</include>
+ <include>**/*.token</include> <include>**/*.xml</include> <include>**/*.conf</include>
+ <include>**/*.info</include> <include>**/*.properties</include> </includes> -->
</testResource>
<testResource>
<directory>src/main/resources</directory>
@@ -297,12 +291,12 @@
<artifactId>nimbus-jose-jwt</artifactId>
<version>5.10</version>
</dependency>
-
+
<!-- OpenId -->
<dependency>
- <groupId>com.nimbusds</groupId>
- <artifactId>oauth2-oidc-sdk</artifactId>
- <version>5.62</version>
+ <groupId>com.nimbusds</groupId>
+ <artifactId>oauth2-oidc-sdk</artifactId>
+ <version>5.62</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java b/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
index 038e402..d76b057 100644
--- a/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
+++ b/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
@@ -26,6 +26,7 @@
import de.ids_mannheim.korap.constant.AuthenticationMethod;
import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.oauth2.openid.OpenIdConfiguration;
/**
* Configuration for Kustvakt full version including properties
@@ -74,6 +75,8 @@
private URL issuer;
private URI issuerURI;
+ private OpenIdConfiguration openidConfig;
+
private RSAPrivateKey rsaPrivateKey;
private JWKSet publicKeySet;
private String rsaKeyId;
@@ -103,6 +106,99 @@
setRSAKeys(properties);
}
+ private void setOpenIdConfiguration (Properties properties)
+ throws URISyntaxException, MalformedURLException {
+ String issuerStr = properties.getProperty("security.jwt.issuer",
+ "https://korap.ids-mannheim.de");
+
+ if (!issuerStr.startsWith("http")) {
+ issuerStr = "http://" + issuerStr;
+ }
+ setIssuer(new URL(issuerStr));
+ setIssuerURI(issuer.toURI());
+
+ issuerStr = issuerURI.toString();
+
+ OpenIdConfiguration openidConfig = new OpenIdConfiguration();
+ openidConfig.setIssuer(issuerStr);
+ openidConfig.setJwks_uri(issuerStr + OpenIdConfiguration.JWKS_ENDPOINT);
+ openidConfig.setRegistration_endpoint(
+ issuerStr + OpenIdConfiguration.CLIENT_REGISTRATION_ENDPOINT);
+ openidConfig.setAuthorization_endpoint(
+ issuerStr + OpenIdConfiguration.AUTHORIZATION_ENDPOINT);
+ openidConfig.setToken_endpoint(
+ issuerStr + OpenIdConfiguration.TOKEN_ENDPOINT);
+
+ String grantTypes = properties.getProperty("openid.grant.types", "");
+ openidConfig.setGrant_types_supported(grantTypes.split(" "));
+
+ String responseTypes =
+ properties.getProperty("openid.response.types", "code");
+ openidConfig.setResponse_types_supported(responseTypes.split(" "));
+
+ String responseModes =
+ properties.getProperty("openid.response.modes", "");
+ openidConfig.setResponse_modes_supported(responseModes.split(" "));
+
+ String clientAuthMethods =
+ properties.getProperty("openid.client.auth.methods", "");
+ openidConfig.setToken_endpoint_auth_methods_supported(
+ clientAuthMethods.split(" "));
+
+ String tokenSigningAlgorithms = properties
+ .getProperty("openid.token.signing.algorithms", "RS256");
+ openidConfig.setToken_endpoint_auth_signing_alg_values_supported(
+ tokenSigningAlgorithms.split(" "));
+
+ String subjectTypes =
+ properties.getProperty("openid.subject.types", "public");
+ openidConfig.setSubject_types_supported(subjectTypes.split(" "));
+
+ String displayTypes =
+ properties.getProperty("openid.display.types", "");
+ openidConfig.setDisplay_values_supported(displayTypes.split(" "));
+
+ String supportedScopes =
+ properties.getProperty("openid.supported.scopes", "");
+ openidConfig.setScopes_supported(supportedScopes.split(" "));
+
+ String claimTypes =
+ properties.getProperty("openid.claim.types", "normal");
+ openidConfig.setClaim_types_supported(claimTypes.split(" "));
+
+ String supportedClaims =
+ properties.getProperty("openid.supported.claims", "");
+ openidConfig.setClaims_supported(supportedClaims.split(" "));
+
+ String claimLocales =
+ properties.getProperty("openid.supported.claim.locales", "");
+ openidConfig.setClaims_locales_supported(claimLocales.split(" "));
+
+ String uiLocales = properties.getProperty("openid.ui.locales", "en");
+ openidConfig.setUi_locales_supported(uiLocales.split(" "));
+
+ boolean supportClaimParam = Boolean.getBoolean(
+ properties.getProperty("openid.support.claim.param", "false"));
+ openidConfig.setClaims_parameter_supported(supportClaimParam);
+
+ openidConfig.setRequest_parameter_supported(false);
+ openidConfig.setRequest_uri_parameter_supported(false);
+ openidConfig.setRequire_request_uri_registration(false);
+ openidConfig.setMutual_tls_sender_constrained_access_tokens(false);
+
+ String privacyPolicy =
+ properties.getProperty("openid.privacy.policy", "");
+ openidConfig.setOp_policy_uri(privacyPolicy);
+
+ String termOfService =
+ properties.getProperty("openid.term.of.service", "");
+ openidConfig.setOp_tos_uri(termOfService);
+
+ String serviceDocURL = properties.getProperty("openid.service.doc", "");
+ openidConfig.setService_documentation(serviceDocURL);
+ this.setOpenidConfig(openidConfig);
+ }
+
private void setRSAKeys (Properties properties)
throws IOException, ParseException, JOSEException {
setRsaKeyId(properties.getProperty("rsa.key.id", ""));
@@ -139,17 +235,6 @@
setRsaPrivateKey(privateKey);
}
- private void setOpenIdConfiguration (Properties properties)
- throws URISyntaxException, MalformedURLException {
- String issuerStr = properties.getProperty("security.jwt.issuer", "");
-
- if (!issuerStr.startsWith("http")) {
- issuerStr = "http://" + issuerStr;
- }
- setIssuer(new URL(issuerStr));
- setIssuerURI(issuer.toURI());
- }
-
private void setOAuth2Configuration (Properties properties) {
setOAuth2passwordAuthentication(
Enum.valueOf(AuthenticationMethod.class, properties.getProperty(
@@ -161,13 +246,13 @@
.parseInt(properties.getProperty("oauth2.max.attempts", "3")));
String scopes = properties.getProperty("oauth2.default.scopes",
- "read_username read_email");
+ "openid preferred_username");
Set<String> scopeSet =
Arrays.stream(scopes.split(" ")).collect(Collectors.toSet());
setDefaultAccessScopes(scopeSet);
String clientScopes = properties.getProperty(
- "oauth2.client.credentials.scopes", "read_client_info");
+ "oauth2.client.credentials.scopes", "client_info");
setClientCredentialsScopes(Arrays.stream(clientScopes.split(" "))
.collect(Collectors.toSet()));
}
@@ -484,4 +569,11 @@
this.rsaKeyId = rsaKeyId;
}
+ public OpenIdConfiguration getOpenidConfig () {
+ return openidConfig;
+ }
+
+ public void setOpenidConfig (OpenIdConfiguration openidConfig) {
+ this.openidConfig = openidConfig;
+ }
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/OpenIdConfiguration.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/OpenIdConfiguration.java
new file mode 100644
index 0000000..499b214
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/OpenIdConfiguration.java
@@ -0,0 +1,699 @@
+package de.ids_mannheim.korap.oauth2.openid;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+
+/**
+ * Defines OpenID configuration.
+ *
+ * Note: some configuration such as display_values_supported and
+ * ui_locales_supported are more relevant to KorAP user interface
+ * component Kalamar.
+ *
+ * @see <a
+ * href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata">OpenID
+ * Provider Metadata</a>
+ * @author margaretha
+ *
+ */
+@JsonInclude(Include.NON_EMPTY)
+public class OpenIdConfiguration {
+
+ public final static String JWKS_ENDPOINT = "/oauth2/openid/jwks";
+ public static final String CLIENT_REGISTRATION_ENDPOINT =
+ "/oauth2/client/register";
+ public static final String AUTHORIZATION_ENDPOINT =
+ "/oauth2/openid/authorize";
+ public static final String TOKEN_ENDPOINT = "/oauth2/openid/token";
+
+ private String issuer;
+ private String jwks_uri;
+
+ private String authorization_endpoint;
+ private String token_endpoint;
+ private String userinfo_endpoint;
+ private String registration_endpoint;
+
+ // Additional endpoints
+ private String introspection_endpoint;
+ private String revocation_endpoint;
+ private String end_session_endpoint;
+
+ private String[] scopes_supported;
+ private String[] response_types_supported;
+ private String[] response_modes_supported;
+ private String[] grant_types_supported;
+
+ private String[] token_endpoint_auth_methods_supported;
+ private String[] token_endpoint_auth_signing_alg_values_supported;
+
+ private String[] id_token_signing_alg_values_supported;
+ private String[] id_token_encryption_alg_values_supported;
+ private String[] id_token_encryption_enc_values_supported;
+
+ private String[] userinfo_signing_alg_values_supported;
+ private String[] userinfo_encryption_alg_values_supported;
+ private String[] userinfo_encryption_enc_values_supported;
+
+ private String[] request_object_signing_alg_values_supported;
+ private String[] request_object_encryption_alg_values_supported;
+ private String[] request_object_encryption_enc_values_supported;
+
+ private String[] subject_types_supported;
+ private String[] acr_values_supported;
+ private String[] display_values_supported;
+ private String[] claim_types_supported;
+ private String[] claims_supported;
+ private String[] claims_locales_supported;
+ private String[] ui_locales_supported;
+
+ private boolean claims_parameter_supported = false;
+ private boolean request_parameter_supported = false;
+ private boolean request_uri_parameter_supported = true;
+ private boolean require_request_uri_registration = false;
+
+ private String op_policy_uri;
+ private String op_tos_uri;
+ private String service_documentation;
+
+ private boolean mutual_tls_sender_constrained_access_tokens = false;
+
+ // OAuth2.0 Discovery
+ // List of Proof Key for Code Exchange (PKCE) code challenge
+ // methods supported on by the authorization server
+ // private String[] code_challenge_methods_supported;
+
+ public String getIssuer () {
+ return issuer;
+ }
+
+ /**
+ * REQUIRED
+ *
+ * @param issuer
+ * The server identifier, typically base-URL
+ */
+ public void setIssuer (String issuer) {
+ this.issuer = issuer;
+ }
+
+ public String getJwks_uri () {
+ return jwks_uri;
+ }
+
+ /**
+ * REQUIRED
+ *
+ * @param jwks_uri
+ * The public JWK set URL
+ */
+ public void setJwks_uri (String jwks_uri) {
+ this.jwks_uri = jwks_uri;
+ }
+
+ public String getAuthorization_endpoint () {
+ return authorization_endpoint;
+ }
+
+ /**
+ * REQUIRED
+ *
+ * @param authorization_endpoint
+ * The authorisation endpoint URL.
+ */
+ public void setAuthorization_endpoint (String authorization_endpoint) {
+ this.authorization_endpoint = authorization_endpoint;
+ }
+
+ public String getToken_endpoint () {
+ return token_endpoint;
+ }
+
+ /**
+ * REQUIRED unless only the Implicit Flow is used.
+ *
+ * @param token_endpoint
+ * The token endpoint URL.
+ */
+ public void setToken_endpoint (String token_endpoint) {
+ this.token_endpoint = token_endpoint;
+ }
+
+ public String getUserinfo_endpoint () {
+ return userinfo_endpoint;
+ }
+
+ /**
+ * RECOMMENDED. The URL MUST use the https scheme.
+ *
+ * @param userinfo_endpoint
+ * The OpenID Connect UserInfo endpoint URL.
+ */
+ public void setUserinfo_endpoint (String userinfo_endpoint) {
+ this.userinfo_endpoint = userinfo_endpoint;
+ }
+
+ public String getRegistration_endpoint () {
+ return registration_endpoint;
+ }
+
+ /**
+ * RECOMMENDED
+ *
+ * @param registration_endpoint
+ * The OAuth 2.0 / OpenID Connect client registration
+ * endpoint
+ * URL.
+ */
+ public void setRegistration_endpoint (String registration_endpoint) {
+ this.registration_endpoint = registration_endpoint;
+ }
+
+ public String[] getScopes_supported () {
+ return scopes_supported;
+ }
+
+ /**
+ * RECOMMENDED
+ *
+ * @param scopes_supported
+ * List of the supported scope values. Certain
+ * values may be omitted for privacy reasons.
+ */
+ public void setScopes_supported (String[] scopes_supported) {
+ this.scopes_supported = scopes_supported;
+ }
+
+ public String[] getResponse_types_supported () {
+ return response_types_supported;
+ }
+
+ /**
+ * REQUIRED
+ *
+ * @param response_types_supported
+ * List of the supported response_type
+ * values.
+ */
+ public void setResponse_types_supported (
+ String[] response_types_supported) {
+ this.response_types_supported = response_types_supported;
+ }
+
+ public String[] getResponse_modes_supported () {
+ return response_modes_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param response_modes_supported
+ * List of the supported response mode
+ * values.
+ */
+ public void setResponse_modes_supported (
+ String[] response_modes_supported) {
+ this.response_modes_supported = response_modes_supported;
+ }
+
+ public String[] getGrant_types_supported () {
+ return grant_types_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param grant_types_supported
+ * List of the supported grant types.
+ */
+ public void setGrant_types_supported (String[] grant_types_supported) {
+ this.grant_types_supported = grant_types_supported;
+ }
+
+ public String[] getAcr_values_supported () {
+ return acr_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param acr_values_supported
+ * List of the supported Authentication Context Class
+ * References.
+ */
+ public void setAcr_values_supported (String[] acr_values_supported) {
+ this.acr_values_supported = acr_values_supported;
+ }
+
+ public String[] getSubject_types_supported () {
+ return subject_types_supported;
+ }
+
+ /**
+ * REQUIRED
+ *
+ * @param subject_types_supported
+ * List of the supported subject (end-user) identifier
+ * types.
+ */
+ public void setSubject_types_supported (String[] subject_types_supported) {
+ this.subject_types_supported = subject_types_supported;
+ }
+
+ public String[] getId_token_signing_alg_values_supported () {
+ return id_token_signing_alg_values_supported;
+ }
+
+ /**
+ * REQUIRED
+ *
+ * @param id_token_signing_alg_values_supported
+ * List of the supported JWS algorithms for
+ * the issued ID tokens to encode claims in a JWT.
+ */
+ public void setId_token_signing_alg_values_supported (
+ String[] id_token_signing_alg_values_supported) {
+ this.id_token_signing_alg_values_supported =
+ id_token_signing_alg_values_supported;
+ }
+
+ public String[] getId_token_encryption_alg_values_supported () {
+ return id_token_encryption_alg_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param id_token_encryption_alg_values_supported
+ * List of the supported JWE algorithms for
+ * the issued ID tokens to encode claims in a JWT.
+ */
+ public void setId_token_encryption_alg_values_supported (
+ String[] id_token_encryption_alg_values_supported) {
+ this.id_token_encryption_alg_values_supported =
+ id_token_encryption_alg_values_supported;
+ }
+
+ public String[] getId_token_encryption_enc_values_supported () {
+ return id_token_encryption_enc_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param id_token_encryption_enc_values_supported
+ * List of the supported JWE encryption methods for
+ * the issued ID tokens to encode claims in a JWT.
+ */
+ public void setId_token_encryption_enc_values_supported (
+ String[] id_token_encryption_enc_values_supported) {
+ this.id_token_encryption_enc_values_supported =
+ id_token_encryption_enc_values_supported;
+ }
+
+ public String[] getUserinfo_signing_alg_values_supported () {
+ return userinfo_signing_alg_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param userinfo_signing_alg_values_supported
+ * List of the supported signing JWS algorithms for
+ * encoding the claims in a JWT returned at the
+ * UserInfo endpoint.
+ */
+ public void setUserinfo_signing_alg_values_supported (
+ String[] userinfo_signing_alg_values_supported) {
+ this.userinfo_signing_alg_values_supported =
+ userinfo_signing_alg_values_supported;
+ }
+
+ public String[] getUserinfo_encryption_alg_values_supported () {
+ return userinfo_encryption_alg_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param userinfo_encryption_alg_values_supported
+ * List of the supported JWE encryption algorithms for
+ * encoding the claims in a JWT returned at the
+ * UserInfo endpoint.
+ */
+ public void setUserinfo_encryption_alg_values_supported (
+ String[] userinfo_encryption_alg_values_supported) {
+ this.userinfo_encryption_alg_values_supported =
+ userinfo_encryption_alg_values_supported;
+ }
+
+ public String[] getUserinfo_encryption_enc_values_supported () {
+ return userinfo_encryption_enc_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param userinfo_encryption_enc_values_supported
+ * List of the supported JWE encryption methods for
+ * encoding the claims in a JWT returned at the
+ * UserInfo endpoint.
+ */
+ public void setUserinfo_encryption_enc_values_supported (
+ String[] userinfo_encryption_enc_values_supported) {
+ this.userinfo_encryption_enc_values_supported =
+ userinfo_encryption_enc_values_supported;
+ }
+
+ public String[] getRequest_object_signing_alg_values_supported () {
+ return request_object_signing_alg_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param request_object_signing_alg_values_supported
+ * JSON array containing a list of supported JWS
+ * signing algorithms (alg values) supported for
+ * Request Objects
+ */
+ public void setRequest_object_signing_alg_values_supported (
+ String[] request_object_signing_alg_values_supported) {
+ this.request_object_signing_alg_values_supported =
+ request_object_signing_alg_values_supported;
+ }
+
+ public String[] getRequest_object_encryption_alg_values_supported () {
+ return request_object_encryption_alg_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param request_object_encryption_alg_values_supported
+ * List of the supported JWE encryption algorithms for
+ * OpenID Connect request objects
+ */
+ public void setRequest_object_encryption_alg_values_supported (
+ String[] request_object_encryption_alg_values_supported) {
+ this.request_object_encryption_alg_values_supported =
+ request_object_encryption_alg_values_supported;
+ }
+
+ public String[] getRequest_object_encryption_enc_values_supported () {
+ return request_object_encryption_enc_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param request_object_encryption_enc_values_supported
+ * List of the supported JWE encryption methods for
+ * OpenID Connect request objects, omitted or empty if
+ * none.
+ */
+ public void setRequest_object_encryption_enc_values_supported (
+ String[] request_object_encryption_enc_values_supported) {
+ this.request_object_encryption_enc_values_supported =
+ request_object_encryption_enc_values_supported;
+ }
+
+ public String[] getToken_endpoint_auth_methods_supported () {
+ return token_endpoint_auth_methods_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param token_endpoint_auth_methods_supported
+ * List of the supported client authentication methods
+ * at the token endpoint.
+ */
+ public void setToken_endpoint_auth_methods_supported (
+ String[] token_endpoint_auth_methods_supported) {
+ this.token_endpoint_auth_methods_supported =
+ token_endpoint_auth_methods_supported;
+ }
+
+ public String[] getToken_endpoint_auth_signing_alg_values_supported () {
+ return token_endpoint_auth_signing_alg_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param token_endpoint_auth_signing_alg_values_supported
+ * List of the supported JWS algorithms for JWT-based
+ * client authentication at the token endpoint
+ */
+ public void setToken_endpoint_auth_signing_alg_values_supported (
+ String[] token_endpoint_auth_signing_alg_values_supported) {
+ this.token_endpoint_auth_signing_alg_values_supported =
+ token_endpoint_auth_signing_alg_values_supported;
+ }
+
+ public String[] getDisplay_values_supported () {
+ return display_values_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param display_values_supported
+ * List of the supported display parameters.
+ */
+ public void setDisplay_values_supported (
+ String[] display_values_supported) {
+ this.display_values_supported = display_values_supported;
+ }
+
+ public String[] getClaim_types_supported () {
+ return claim_types_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param claim_types_supported
+ * List of the supported OpenID Connect claim types.
+ */
+ public void setClaim_types_supported (String[] claim_types_supported) {
+ this.claim_types_supported = claim_types_supported;
+ }
+
+ public String[] getClaims_supported () {
+ return claims_supported;
+ }
+
+ /**
+ * RECOMMENDED
+ *
+ * @param claims_supported
+ * List of the supported OpenID Connect claims.
+ */
+ public void setClaims_supported (String[] claims_supported) {
+ this.claims_supported = claims_supported;
+ }
+
+ public String getService_documentation () {
+ return service_documentation;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param service_documentation
+ * The service documentation URL
+ */
+ public void setService_documentation (String service_documentation) {
+ this.service_documentation = service_documentation;
+ }
+
+ public String[] getClaims_locales_supported () {
+ return claims_locales_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param claims_locales_supported
+ * List of the supported OpenID Connect claims locales
+ */
+ public void setClaims_locales_supported (
+ String[] claims_locales_supported) {
+ this.claims_locales_supported = claims_locales_supported;
+ }
+
+ public String[] getUi_locales_supported () {
+ return ui_locales_supported;
+ }
+
+ /**
+ * OPTIONAL
+ *
+ * @param ui_locales_supported
+ * List of the supported UI locales
+ */
+ public void setUi_locales_supported (String[] ui_locales_supported) {
+ this.ui_locales_supported = ui_locales_supported;
+ }
+
+ public boolean isClaims_parameter_supported () {
+ return claims_parameter_supported;
+ }
+
+ /**
+ * OPTIONAL. Default false.
+ *
+ * @param claims_parameter_supported
+ * Specifies whether the claims request parameter is
+ * supported.
+ */
+ public void setClaims_parameter_supported (
+ boolean claims_parameter_supported) {
+ this.claims_parameter_supported = claims_parameter_supported;
+ }
+
+ public boolean isRequest_parameter_supported () {
+ return request_parameter_supported;
+ }
+
+ /**
+ * OPTIONAL. Default false.
+ *
+ * @param request_parameter_supported
+ * Specifies whether the request parameter is
+ * supported.
+ */
+ public void setRequest_parameter_supported (
+ boolean request_parameter_supported) {
+ this.request_parameter_supported = request_parameter_supported;
+ }
+
+ public boolean isRequest_uri_parameter_supported () {
+ return request_uri_parameter_supported;
+ }
+
+ /**
+ * OPTIONAL. Default true.
+ *
+ * @param request_uri_parameter_supported
+ * Specifies whether the request_uri parameter is
+ * supported.
+ */
+ public void setRequest_uri_parameter_supported (
+ boolean request_uri_parameter_supported) {
+ this.request_uri_parameter_supported = request_uri_parameter_supported;
+ }
+
+ public boolean isRequire_request_uri_registration () {
+ return require_request_uri_registration;
+ }
+
+ /**
+ * OPTIONAL. Default false.
+ *
+ * @param require_request_uri_registration
+ * Specifies whether request URIs must be registered
+ * for a client.
+ */
+ public void setRequire_request_uri_registration (
+ boolean require_request_uri_registration) {
+ this.require_request_uri_registration =
+ require_request_uri_registration;
+ }
+
+ public String getOp_policy_uri () {
+ return op_policy_uri;
+ }
+
+ /**
+ * OPTIONAL. URL that the OpenID Provider provides to the person
+ * registering the Client to read about the requirements on
+ * how the client can use the data provided by the OpenID
+ * Provider. The registration process SHOULD display this URL to
+ * the person registering the Client if it is given.
+ *
+ * @param op_policy_uri
+ * The privacy policy document URL, omitted if none.
+ */
+ public void setOp_policy_uri (String op_policy_uri) {
+ this.op_policy_uri = op_policy_uri;
+ }
+
+ public String getOp_tos_uri () {
+ return op_tos_uri;
+ }
+
+ /**
+ * @param op_tos_uri
+ * The terms of service document URL, omitted if none.
+ */
+ public void setOp_tos_uri (String op_tos_uri) {
+ this.op_tos_uri = op_tos_uri;
+ }
+
+ public String getIntrospection_endpoint () {
+ return introspection_endpoint;
+ }
+
+ /**
+ * ADDITIONAL
+ *
+ * @param introspection_endpoint
+ * The token introspection endpoint URL.
+ */
+ public void setIntrospection_endpoint (String introspection_endpoint) {
+ this.introspection_endpoint = introspection_endpoint;
+ }
+
+ public String getRevocation_endpoint () {
+ return revocation_endpoint;
+ }
+
+ /**
+ * ADDITIONAL
+ *
+ * @param revocation_endpoint
+ * The token revocation endpoint URL.
+ */
+ public void setRevocation_endpoint (String revocation_endpoint) {
+ this.revocation_endpoint = revocation_endpoint;
+ }
+
+ public String getEnd_session_endpoint () {
+ return end_session_endpoint;
+ }
+
+ /**
+ * ADDITIONAL
+ *
+ * @param end_session_endpoint
+ * The OpenID Connect logout endpoint URL, omitted if
+ * disabled.
+ */
+ public void setEnd_session_endpoint (String end_session_endpoint) {
+ this.end_session_endpoint = end_session_endpoint;
+ }
+
+ public boolean isMutual_tls_sender_constrained_access_tokens () {
+ return mutual_tls_sender_constrained_access_tokens;
+ }
+
+ /**
+ * OPTIONAL. Default false.
+ *
+ * @see <a
+ * href="https://tools.ietf.org/id/draft-ietf-oauth-mtls-03.html#server_metadata">Mutual
+ * TLS Profile for OAuth 2.0</a>
+ * @param mutual_tls_sender_constrained_access_tokens
+ * specifies whether issue of client X.509 certificate
+ * bound access tokens is supported, omitted
+ * implies no support.
+ */
+ public void setMutual_tls_sender_constrained_access_tokens (
+ boolean mutual_tls_sender_constrained_access_tokens) {
+ this.mutual_tls_sender_constrained_access_tokens =
+ mutual_tls_sender_constrained_access_tokens;
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/service/OpenIdConfigService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/service/OpenIdConfigService.java
new file mode 100644
index 0000000..0820f3f
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/openid/service/OpenIdConfigService.java
@@ -0,0 +1,18 @@
+package de.ids_mannheim.korap.oauth2.openid.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.config.FullConfiguration;
+import de.ids_mannheim.korap.oauth2.openid.OpenIdConfiguration;
+
+@Service
+public class OpenIdConfigService {
+
+ @Autowired
+ private FullConfiguration config;
+
+ public OpenIdConfiguration retrieveOpenIdConfigInfo () {
+ return config.getOpenidConfig();
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java
index 29b9856..cf4fe81 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2WithOpenIdController.java
@@ -31,9 +31,11 @@
import com.sun.jersey.spi.container.ResourceFilters;
import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth2.openid.OpenIdConfiguration;
import de.ids_mannheim.korap.oauth2.openid.OpenIdHttpRequestWrapper;
import de.ids_mannheim.korap.oauth2.openid.service.JWKService;
import de.ids_mannheim.korap.oauth2.openid.service.OpenIdAuthorizationService;
+import de.ids_mannheim.korap.oauth2.openid.service.OpenIdConfigService;
import de.ids_mannheim.korap.oauth2.openid.service.OpenIdTokenService;
import de.ids_mannheim.korap.security.context.TokenContext;
import de.ids_mannheim.korap.web.OpenIdResponseHandler;
@@ -52,6 +54,9 @@
@Autowired
private JWKService jwkService;
@Autowired
+ private OpenIdConfigService configService;
+
+ @Autowired
private OpenIdResponseHandler openIdResponseHandler;
/**
@@ -199,9 +204,23 @@
* @see "RFC 7517 regarding JWK (Json Web Key) and JWK Set"
*/
@GET
- @Path("key/public")
+ @Path("jwks")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
- public String retrievePublicKeys () {
+ public String requestPublicKeys () {
return jwkService.generatePublicKeySetJson();
}
+
+ /**
+ * When supporting discovery, must be available at
+ * {issuer_uri}/.well-known/openid-configuration
+ * @return
+ *
+ * @return
+ */
+ @GET
+ @Path("config")
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ public OpenIdConfiguration requestOpenIdConfig () {
+ return configService.retrieveOpenIdConfigInfo();
+ }
}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/AvailabilityTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/AvailabilityTest.java
index 98502ea..15d627f 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/AvailabilityTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/AvailabilityTest.java
@@ -1,8 +1,8 @@
package de.ids_mannheim.korap.web.controller;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -103,35 +103,6 @@
}
- private void checkAndAll (String json) throws KustvaktException {
- JsonNode node = JsonUtils.readTree(json);
- assertNotNull(node);
- assertEquals("availability(ALL)",
- node.at("/collection/rewrites/0/scope").asText());
- assertEquals("operation:insertion",
- node.at("/collection/rewrites/0/operation").asText());
-
- assertEquals("operation:and",
- node.at("/collection/operation").asText());
-
- node = node.at("/collection/operands/0");
- assertEquals("operation:or", node.at("/operation").asText());
-
- assertEquals("match:eq", node.at("/operands/0/match").asText());
- assertEquals("match:eq", node.at("/operands/0/match").asText());
- assertEquals("type:regex", node.at("/operands/0/type").asText());
- assertEquals("availability", node.at("/operands/0/key").asText());
- assertEquals("CC-BY.*", node.at("/operands/0/value").asText());
-
- node = node.at("/operands/1");
- assertEquals("operation:or", node.at("/operation").asText());
- assertEquals("match:eq", node.at("/operands/0/match").asText());
- assertEquals("ACA.*", node.at("/operands/0/value").asText());
- assertEquals("match:eq", node.at("/operands/1/match").asText());
- assertEquals("QAO.*", node.at("/operands/1/value").asText());
-
- }
-
private void checkAndAllWithACA (String json) throws KustvaktException {
JsonNode node = JsonUtils.readTree(json);
assertNotNull(node);
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
index 97efe8d..497218c 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
@@ -171,7 +171,7 @@
MultivaluedMap<String, String> authForm = new MultivaluedMapImpl();
authForm.add("response_type", "code");
authForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
- authForm.add("scope", "read_username");
+ authForm.add("scope", "username");
ClientResponse response =
requestAuthorizationConfidentialClient(authForm);
@@ -181,7 +181,7 @@
String code = params.get("code").get(0);
String scopes = params.get("scope").get(0);
- assertEquals(scopes, "read_username");
+ assertEquals(scopes, "username");
MultivaluedMap<String, String> tokenForm = new MultivaluedMapImpl();
tokenForm.add("grant_type", "authorization_code");
@@ -241,7 +241,7 @@
MultivaluedMap<String, String> authForm = new MultivaluedMapImpl();
authForm.add("response_type", "code");
authForm.add("client_id", "fCBbQkAyYzI4NzUxMg");
- authForm.add("scope", "read_username");
+ authForm.add("scope", "username");
authForm.add("redirect_uri", uri);
ClientResponse response =
@@ -437,7 +437,7 @@
form.add("grant_type", "client_credentials");
form.add("client_id", "fCBbQkAyYzI4NzUxMg");
form.add("client_secret", "secret");
- form.add("scope", "read_username read_client_info");
+ form.add("scope", "preferred_username client_info");
ClientResponse response = requestToken(form);
String entity = response.getEntity(String.class);
@@ -450,7 +450,7 @@
assertEquals(TokenType.BEARER.toString(),
node.at("/token_type").asText());
assertNotNull(node.at("/expires_in").asText());
- assertEquals("read_client_info", node.at("/scope").asText());
+ assertEquals("client_info", node.at("/scope").asText());
}
@Test
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2OpenIdControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2OpenIdControllerTest.java
index 5459c6d..6594fdd 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2OpenIdControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2OpenIdControllerTest.java
@@ -316,7 +316,7 @@
@Test
public void testPublicKeyAPI () throws KustvaktException {
ClientResponse response = resource().path("oauth2").path("openid")
- .path("key").path("public").get(ClientResponse.class);
+ .path("jwks").get(ClientResponse.class);
String entity = response.getEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
assertEquals(1,node.at("/keys").size());
@@ -326,4 +326,18 @@
assertNotNull(node.at("/e").asText());
assertNotNull(node.at("/n").asText());
}
+
+ @Test
+ public void testOpenIDConfiguration () throws KustvaktException {
+ ClientResponse response = resource().path("oauth2").path("openid")
+ .path("config").get(ClientResponse.class);
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertNotNull(node.at("/issuer"));
+ assertNotNull(node.at("/authorization_endpoint"));
+ assertNotNull(node.at("/token_endpoint"));
+ assertNotNull(node.at("/response_types_supported"));
+ assertNotNull(node.at("/subject_types_supported"));
+ assertNotNull(node.at("/id_token_signing_alg_values_supported"));
+ }
}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceInfoControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceInfoControllerTest.java
index e96e523..fa40e73 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceInfoControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/ResourceInfoControllerTest.java
@@ -14,7 +14,6 @@
import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.constant.TokenType;
import de.ids_mannheim.korap.exceptions.KustvaktException;
import de.ids_mannheim.korap.utils.JsonUtils;
import de.ids_mannheim.korap.web.FastJerseyTest;
diff --git a/full/src/test/resources/kustvakt-test.conf b/full/src/test/resources/kustvakt-test.conf
index 48ce51c..9061918 100644
--- a/full/src/test/resources/kustvakt-test.conf
+++ b/full/src/test/resources/kustvakt-test.conf
@@ -43,18 +43,36 @@
## options referring to the security module!
-## OAuth
+## OAuth
### (see de.ids_mannheim.korap.constant.AuthenticationMethod for possible
### oauth.password.authentication values)
-oauth.password.authentication = TEST
-oauth.native.client.host=korap.ids-mannheim.de
+oauth2.password.authentication = TEST
+oauth2.native.client.host = korap.ids-mannheim.de
oauth2.max.attempts = 2
# -- scopes separated by space
-oauth2.default.scopes = openid read_username read_email
-oauth2.client.credentials.scopes = read_client_info
+oauth2.default.scopes = openid username email
+oauth2.client.credentials.scopes = client_info
+
+## OpenId
+### multiple values are separated by space
+openid.grant.types = authorization_code
+openid.response.types = code
+openid.response.modes = query
+openid.client.auth.methods = client_secret_basic client_secret_post
+openid.token.signing.algorithms = RS256
+openid.subject.types = public
+openid.display.types = page
+openid.supported.scopes = openid email
+openid.support.claim.param = false
+openid.claim.types = normal
+openid.supported.claims = iss sub aud exp iat
+openid.ui.locales = en
+#openid.privacy.policy =
+#openid.term.of.service =
+openid.service.doc = https://github.com/KorAP/Kustvakt/wiki
## JWT
-security.jwt.issuer=korap.ids-mannheim.de
+security.jwt.issuer=https://korap.ids-mannheim.de
## JWK
rsa.private = kustvakt_rsa.key