Allow empty token endpoint for implicit flow (#45038)
When using the implicit flow in OpenID Connect, the op.token_endpoint_url should not be mandatory as there is no need to contact the token endpoint of the OP.
This commit is contained in:
parent
ddcc38cf1c
commit
99ddb8b3d8
|
@ -23,9 +23,10 @@ public class OpenIdConnectProviderConfiguration {
|
|||
private final String jwkSetPath;
|
||||
|
||||
public OpenIdConnectProviderConfiguration(Issuer issuer, String jwkSetPath, URI authorizationEndpoint,
|
||||
URI tokenEndpoint, @Nullable URI userinfoEndpoint, @Nullable URI endsessionEndpoint) {
|
||||
@Nullable URI tokenEndpoint, @Nullable URI userinfoEndpoint,
|
||||
@Nullable URI endsessionEndpoint) {
|
||||
this.authorizationEndpoint = Objects.requireNonNull(authorizationEndpoint, "Authorization Endpoint must be provided");
|
||||
this.tokenEndpoint = Objects.requireNonNull(tokenEndpoint, "Token Endpoint must be provided");
|
||||
this.tokenEndpoint = tokenEndpoint;
|
||||
this.userinfoEndpoint = userinfoEndpoint;
|
||||
this.endsessionEndpoint = endsessionEndpoint;
|
||||
this.issuer = Objects.requireNonNull(issuer, "OP Issuer must be provided");
|
||||
|
|
|
@ -281,25 +281,31 @@ public class OpenIdConnectRealm extends Realm implements Releasable {
|
|||
// This should never happen as it's already validated in the settings
|
||||
throw new SettingsException("Invalid URI: " + OP_AUTHORIZATION_ENDPOINT.getKey(), e);
|
||||
}
|
||||
String responseType = require(config, RP_RESPONSE_TYPE);
|
||||
String tokenEndpointString = config.getSetting(OP_TOKEN_ENDPOINT);
|
||||
if (responseType.equals("code") && tokenEndpointString.isEmpty()) {
|
||||
throw new SettingsException("The configuration setting [" + OP_TOKEN_ENDPOINT.getConcreteSettingForNamespace(name()).getKey()
|
||||
+ "] is required when [" + RP_RESPONSE_TYPE.getConcreteSettingForNamespace(name()).getKey() + "] is set to \"code\"");
|
||||
}
|
||||
URI tokenEndpoint;
|
||||
try {
|
||||
tokenEndpoint = new URI(require(config, OP_TOKEN_ENDPOINT));
|
||||
tokenEndpoint = tokenEndpointString.isEmpty() ? null : new URI(tokenEndpointString);
|
||||
} catch (URISyntaxException e) {
|
||||
// This should never happen as it's already validated in the settings
|
||||
throw new SettingsException("Invalid URL: " + OP_TOKEN_ENDPOINT.getKey(), e);
|
||||
}
|
||||
URI userinfoEndpoint;
|
||||
try {
|
||||
userinfoEndpoint = (config.getSetting(OP_USERINFO_ENDPOINT, () -> null) == null) ? null :
|
||||
new URI(config.getSetting(OP_USERINFO_ENDPOINT, () -> null));
|
||||
userinfoEndpoint = (config.getSetting(OP_USERINFO_ENDPOINT).isEmpty()) ? null :
|
||||
new URI(config.getSetting(OP_USERINFO_ENDPOINT));
|
||||
} catch (URISyntaxException e) {
|
||||
// This should never happen as it's already validated in the settings
|
||||
throw new SettingsException("Invalid URI: " + OP_USERINFO_ENDPOINT.getKey(), e);
|
||||
}
|
||||
URI endsessionEndpoint;
|
||||
try {
|
||||
endsessionEndpoint = (config.getSetting(OP_ENDSESSION_ENDPOINT, () -> null) == null) ? null :
|
||||
new URI(config.getSetting(OP_ENDSESSION_ENDPOINT, () -> null));
|
||||
endsessionEndpoint = (config.getSetting(OP_ENDSESSION_ENDPOINT).isEmpty()) ? null :
|
||||
new URI(config.getSetting(OP_ENDSESSION_ENDPOINT));
|
||||
} catch (URISyntaxException e) {
|
||||
// This should never happen as it's already validated in the settings
|
||||
throw new SettingsException("Invalid URI: " + OP_ENDSESSION_ENDPOINT.getKey(), e);
|
||||
|
|
|
@ -86,7 +86,7 @@ public class OpenIdConnectRealmSettingsTests extends ESTestCase {
|
|||
Matchers.containsString(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.OP_AUTHORIZATION_ENDPOINT)));
|
||||
}
|
||||
|
||||
public void testMissingTokenEndpointThrowsError() {
|
||||
public void testMissingTokenEndpointThrowsErrorInCodeFlow() {
|
||||
final Settings.Builder settingsBuilder = Settings.builder()
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.OP_AUTHORIZATION_ENDPOINT), "https://op.example.com/login")
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.OP_ISSUER), "https://op.example.com")
|
||||
|
@ -103,6 +103,22 @@ public class OpenIdConnectRealmSettingsTests extends ESTestCase {
|
|||
Matchers.containsString(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.OP_TOKEN_ENDPOINT)));
|
||||
}
|
||||
|
||||
public void testMissingTokenEndpointIsAllowedInImplicitFlow() {
|
||||
final Settings.Builder settingsBuilder = Settings.builder()
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.OP_AUTHORIZATION_ENDPOINT), "https://op.example.com/login")
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.OP_ISSUER), "https://op.example.com")
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.OP_JWKSET_PATH), "https://op.example.com/jwks.json")
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.PRINCIPAL_CLAIM.getClaim()), "sub")
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.RP_REDIRECT_URI), "https://rp.my.com")
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.RP_CLIENT_ID), "rp-my")
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.RP_RESPONSE_TYPE), "id_token token");
|
||||
settingsBuilder.setSecureSettings(getSecureSettings());
|
||||
final OpenIdConnectRealm realm = new OpenIdConnectRealm(buildConfig(settingsBuilder.build()), null, null);
|
||||
assertNotNull(realm);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testInvalidTokenEndpointThrowsError() {
|
||||
final Settings.Builder settingsBuilder = Settings.builder()
|
||||
.put(getFullSettingKey(REALM_NAME, OpenIdConnectRealmSettings.OP_AUTHORIZATION_ENDPOINT), "https://op.example.com/login")
|
||||
|
|
Loading…
Reference in New Issue