-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OpenID Connect Realm base functionality #37009
OpenID Connect Realm base functionality #37009
Conversation
- Added Realm settings - Added RP/OP configuration classes - Added realm configuration tests - Completed the Prepare Auethentication API
Pinging @elastic/es-security |
@elasticmachine test this please |
@elasticmachine run the gradle build tests 2 please |
.../java/org/elasticsearch/xpack/core/security/action/oidc/OpenIdConnectAuthenticateAction.java
Show resolved
Hide resolved
public class OpenIdConnectAuthenticateRequest extends ActionRequest { | ||
|
||
/** | ||
* The URI were the OP redirected the browser after the authentication attempt. This is passed as is from the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/were/where
...elasticsearch/xpack/core/security/action/oidc/OpenIdConnectPrepareAuthenticationRequest.java
Outdated
Show resolved
Hide resolved
...java/org/elasticsearch/xpack/core/security/action/oidc/OpenIdConnectAuthenticateRequest.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
@Override | ||
public void readFrom(StreamInput in) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to see us start using Writeable
for everything new. That would make this throw a UnsupportedOperationException
.
...elasticsearch/xpack/core/security/action/oidc/OpenIdConnectPrepareAuthenticationRequest.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/RealmSettings.java
Outdated
Show resolved
Hide resolved
...a/org/elasticsearch/xpack/security/action/oidc/TransportOpenIdConnectAuthenticateAction.java
Outdated
Show resolved
Hide resolved
...ugin/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OPConfiguration.java
Outdated
Show resolved
Hide resolved
...n/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectRealm.java
Outdated
Show resolved
Hide resolved
@jkakavas when targeting a feature branch, its best to ensure you keep it up to date if you merge master into your PR otherwise it looks like the change you're merging is a lot bigger. I went ahead and updated feature-oidc-realm to be in sync with current master. This changed the PR diff from 8000 lines to 1400 lines. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
public static final Setting.AffixSetting<String> OP_TOKEN_ENDPOINT | ||
= RealmSettings.simpleString(TYPE, "op.token_endpoint", Setting.Property.NodeScope); | ||
public static final Setting.AffixSetting<String> OP_USERINFO_ENDPOINT | ||
= RealmSettings.simpleString(TYPE, "op.userinfo_endpoint", Setting.Property.NodeScope); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we get by without the the user_info endpoint. I sense this can be added latter if there are integrations that absolutely require it? Just a thought....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave it in as it is not a required setting ( so it won't produce any errors/warnings if not configured) and I plan to have the ability to query the user_info endpoint as a configurable part of the authentication flow from the beginning.
public static final Setting.AffixSetting<String> RP_REDIRECT_URI | ||
= RealmSettings.simpleString(TYPE, "rp.redirect_uri", Setting.Property.NodeScope); | ||
public static final Setting.AffixSetting<String> RP_RESPONSE_TYPE | ||
= RealmSettings.simpleString(TYPE, "rp.response_type", Setting.Property.NodeScope); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can infer this? Keep it to code
or id_token
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right that it doesn't make much sense now with the allowed values being code
and implicit
. The original thought was to infer "id_token" from the value implicit, but as also proven by me not adding it, this is probably an unnecessary optimization for the user. I will change implicit
to id_token
to be in line with the specification
|
||
private String realmName; | ||
private String state; | ||
private String nonce; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's easier to reason if we generate the state
and nonce
. OIDC allows for too much flexibility already....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went back and forth on this for some time. Agreed, there is no strong argument against allowing Kibana (or any other facilitator ) to determine the nonce and state. I will address this
- Remove the possibility for the facilitator to request a specific nonce or state value and instead generate them always in ES. - Fix the response_type allowed values
If I'm reading this correctly , I plan on adding support for a subset of the Dynamic Discovery specification (at least the part of consuming the OP metadata |
and
@elasticmachine I will try and ask you to run the gradle build tests 1 and then also run the gradle build tests 2 if you may |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the approvals from others, I didn't read everything, but I left some comments.
Feel free to address them in a followup if you'd like to get this one merged.
*/ | ||
public class RestOpenIdConnectPrepareAuthenticationAction extends OpenIdConnectBaseRestHandler { | ||
|
||
static final ObjectParser<OpenIdConnectPrepareAuthenticationRequest, Void> PARSER = new ObjectParser<>("oidc_prepare_auithentication", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/auith/auth/
|
||
/** | ||
* The state value that either we or the facilitator generated for this specific flow and that was stored at the user's session with | ||
* the facilitator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These java docs ("the faciliator generated") are no longer true.
.filter(r -> r instanceof OpenIdConnectRealm) | ||
.map(r -> (OpenIdConnectRealm) r) | ||
.filter(r -> r.name().equals(request.getRealmName())) | ||
.collect(Collectors.toList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just call Realms.realm(String)
?
private String nonce; | ||
|
||
/** | ||
* @param redirectUri The URI were the OP redirected the browser after the authentication event at the OP. This is passed as is from the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/were/where/
|
||
@Override | ||
public String principal() { | ||
return "<unauthenticated-oidc-user>"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the confusion that users have around unauthenticated-saml-user
we used a different pattern on just "<Kerberos Token>"
for Kerberos.
My gut feel is to do something similar here "<OIDC Token>"
?
this.clientId = Objects.requireNonNull(clientId, "RP Client ID must be provided"); | ||
this.redirectUri = Objects.requireNonNull(redirectUri, "RP Redirect URI must be provided"); | ||
if (Strings.hasText(responseType) == false) { | ||
throw new IllegalArgumentException("Response type must be provided"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these error messages need to be clear about the Setting
that was incorrect.
Ideally we'd do validation in the Setting
itself, but if not, then I think the validation ought to be done in the context of the Realm so that it can reference the setting key.
Otherwise we'll get lots of questions from users about "I got an error saying Response type must be provided
but I don't know where to configure it."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense Tim, I'll address that. I'll do it in the Realm (this is what we do in other realms too I think) but I can move this to the Setting with a validator if need be !
Thanks for the valuable feedback Tim, I'll go ahead and address this now before merging |
run the gradle build tests 2 |
run the gradle build tests 2 and also run the gradle build tests 1 |
|
run the gradle build tests 2 |
run the gradle build tests 1 |
run the gradle build tests 1 |
1 similar comment
run the gradle build tests 1 |
:sigh: run the gradle build tests 1 |
run the gradle build tests 1 just in case we get lucky |
20th time is the charm as an old Greek proverb says, run the gradle build tests 1 |
This commit adds * An OpenID Connect Realm definition * Necessary OpenID Connect Realm settings to support Authorization code grant and Implicit grant flows * Rest and Transport Action and Request/Response objects for initiating and completing the authentication flow * Functionality for generating OIDC Authentication Request URIs Unit tests Notably missing (to be handled in subsequent PRs): * The actual implementation of the authentication flows * Necessary JW{T,S,E} functionality Relates: elastic#35339
This commit adds an OpenID Connect authentication realm to elasticsearch. Elasticsearch (with the assistance of kibana or another web component) acts as an OpenID Connect Relying Party and supports the Authorization Code Grant and Implicit flows as described in http://ela.st/oidc-spec. It adds support for consuming and verifying signed ID Tokens, both RP initiated and 3rd party initiated Single Sign on and RP initiated signle logout. It also adds an OpenID Connect Provider in the idp-fixture to be used for the associated integration tests. The code in this commit has been tracked in a feature branch and has been previously reviewed and approved in : #37009 #37787 #38474 #38475 #40262
This commit adds an OpenID Connect authentication realm to elasticsearch. Elasticsearch (with the assistance of kibana or another web component) acts as an OpenID Connect Relying Party and supports the Authorization Code Grant and Implicit flows as described in http://ela.st/oidc-spec. It adds support for consuming and verifying signed ID Tokens, both RP initiated and 3rd party initiated Single Sign on and RP initiated signle logout. It also adds an OpenID Connect Provider in the idp-fixture to be used for the associated integration tests. The code in this commit has been tracked in a feature branch and has been previously reviewed and approved in : elastic#37009 elastic#37787 elastic#38474 elastic#38475 elastic#40262
This commit adds an OpenID Connect authentication realm to elasticsearch. Elasticsearch (with the assistance of kibana or another web component) acts as an OpenID Connect Relying Party and supports the Authorization Code Grant and Implicit flows as described in http://ela.st/oidc-spec. It adds support for consuming and verifying signed ID Tokens, both RP initiated and 3rd party initiated Single Sign on and RP initiated signle logout. It also adds an OpenID Connect Provider in the idp-fixture to be used for the associated integration tests. The code in this commit has been tracked in a feature branch and has been previously reviewed and approved in : elastic#37009 elastic#37787 elastic#38474 elastic#38475 elastic#40262
For the benefit of splitting this feature to manageable/reviewable(sic) chuncks, this commit adds
Notably missing (to be handled in subsequent PRs):
Relates: #35339