Skip to content

Conversation

@bizybot
Copy link
Contributor

@bizybot bizybot commented Jun 27, 2018

Till now we had support for 'Basic', 'Bearer' auth schemes and
this was sufficient for us to reply WWW-Authenticate header
with one value either for Basic or Bearer for unauthorized
access.
After introducing Kerberos we will be supporting Negotiate scheme.
As per RFC7235,
we may respond with the list of challenges. This list is of auth
schemes supported by the server. We can also have custom Realms
defining their own response header value for 'WWW-Authenticate'
header. This commit introduces a getWWWAuthenticateHeaderValue
in Realm to identify the scheme which it wants to use. By default,
it uses 'Basic' auth scheme. This can be overridden
by realms like KerberosRealm to specify 'Negotiate' scheme or OAuth
to specify 'Bearer' or custom realms added by security extensions to
specify their own scheme.
SAML specifications do not specify anything related to the header but
unofficially many have used 'SAML' as auth scheme or used 'Bearer'
auth scheme for passing SAML tokens.
But most of the realms would use the existing schemes
like 'Basic', 'Digest', 'Bearer', 'Negotiate' etc.
At the startup, Security#createComponents will take care of
creating DefaultAuthenticationFailureHandler with default
response header values for 'WWW-Authenticate' as a list of configured
and enabled auth schemes.

Till now we had support for 'Basic', 'Bearer' auth schemes and
this was sufficient for us to reply `WWW-Authenticate` header
with one value either for `Basic` or `Bearer` for unauthorized
access.
After introducing Kerberos we will be supporting `Negotiate` scheme.
As per [RFC7235](https://tools.ietf.org/html/rfc7235#section-4.1),
we may respond with the list of challenges. This list is of auth
schemes supported by the server. We can also have custom Realms
defining their own response header value for 'WWW-Authenticate'
header. This commit introduces a `getWWWAuthenticateHeaderValue`
in `Realm` to identify the scheme which it wants to use. By default
it uses 'Basic' auth scheme. This can be overriden
by realms like KerberosRealm to specify 'Negotiate' scheme or OAuth
to specify 'Bearer' or custom realms added by security extensions to
specify their own scheme.
SAML specifications do not specify anything related to the header but
unofficially many have used 'SAML' as auth scheme or used 'Bearer'
auth scheme for passing SAML tokens.
But most of the realms would use the existing schemes
like 'Basic', 'Digest', 'Bearer', 'Negotiate' etc.
At the startup, `Security#createComponents` will take care of
creating `DefaultAuthenticationFailureHandler` with default
response header values for 'WWW-Authenticate' as a list of configured
and enabled auth schemes.
@bizybot bizybot added >feature :Security/Authentication Logging in, Usernames/passwords, Realms (Native/LDAP/AD/SAML/PKI/etc) labels Jun 27, 2018
@bizybot bizybot requested review from jaymode and tvernum June 27, 2018 01:09
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security

* @deprecated @see {@link #DefaultAuthenticationFailureHandler(List)}
*/
@Deprecated
public DefaultAuthenticationFailureHandler() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This deprecated default constructor is added to not break security extensions.

Yogesh Gaikwad added 2 commits June 27, 2018 13:30
As Realms can return empty list due to license restriction
adding default 'Basic' scheme to the authentication failure
handler header value. Refactoring to create authentication
failure handler in extracted method.
*
* @return value to be returned in 'WWW-Authenticate' response header.
*/
public String getWWWAuthenticateHeaderValue() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know I normally lean towards "just build what you need", but this method feels way too specific to me.
Did you consider a getAuthenticationFailureHeaders() method instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestion yes, you right it's too specific and I also felt it should return a List of supported schemes. Usually, the authentication failure response headers will be populated in the ElasticsearchSecurityException and the method name you suggested might confuse. How about getSupportedAuthenticateChallenges instead? or any other suggestion. Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider a getAuthenticationFailureHeaders() method instead?

+1. I feel like this is the way to go. Ultimately this might allow us to remove the authentication failure handler (way off low priority future idea)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, are we thinking of letting the realms drive everything? Because I do see the value in it. Current flow makes us look at the code all over to see where the exception was populated whether it was populated with right headers, that too outside the realm if not then add those headers. I will make it a generic name as suggested. But would like to know more on what other headers do you foresee that needs to be sent and might be the realm driven?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to let the realms handle this.
I don't know what other headers we could expect - but that's kind of the point, we can just support a relatively generic method and let custom realms do whatever they need. My guess is that anything other than WWW-Authenticate would be due to weird proprietary protocols, but if they exist then we can support them.

@bizybot bizybot force-pushed the kerberos/authnchallenge branch from 0c24b1a to 435d19c Compare June 29, 2018 04:36
@bizybot
Copy link
Contributor Author

bizybot commented Jun 29, 2018

Hi @jaymode, @tvernum I have addressed your review comments. Please take a look when you get some time. Thank you.

Copy link
Member

@jaymode jaymode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some minor comments. Otherwise this change LGTM

*/
public DefaultAuthenticationFailureHandler(Map<String, List<String>> failureResponseHeaders) {
if (failureResponseHeaders == null || failureResponseHeaders.isEmpty()) {
failureResponseHeaders = new HashMap<>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just use Collections.singletonMap

* Creates an instance of {@link ElasticsearchSecurityException} with
* {@link RestStatus#UNAUTHORIZED} status.
* <p>
* Also adds response headers as configured
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

complete the thought, configured where?

*/
public Map<String, List<String>> getAuthenticationFailureHeaders() {
final Map<String, List<String>> headers = new HashMap<>();
headers.put("WWW-Authenticate", Arrays.asList("Basic realm=\"" + XPackField.SECURITY + "\" charset=\"UTF-8\""));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Collections.singletonMap here and Collections.singletonList

@bizybot bizybot merged commit 52367f2 into elastic:feature/kerberos Jul 3, 2018
@bizybot bizybot deleted the kerberos/authnchallenge branch July 3, 2018 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

>feature :Security/Authentication Logging in, Usernames/passwords, Realms (Native/LDAP/AD/SAML/PKI/etc)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants