Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@ public final class AuthenticateResponse {
static final ParseField LOOKUP_REALM = new ParseField("lookup_realm");
static final ParseField REALM_NAME = new ParseField("name");
static final ParseField REALM_TYPE = new ParseField("type");
static final ParseField AUTHENTICATION_TYPE = new ParseField("authentication_type");

@SuppressWarnings("unchecked")
private static final ConstructingObjectParser<AuthenticateResponse, Void> PARSER = new ConstructingObjectParser<>(
"client_security_authenticate_response", true,
a -> new AuthenticateResponse(new User((String) a[0], ((List<String>) a[1]), (Map<String, Object>) a[2],
(String) a[3], (String) a[4]), (Boolean) a[5], (RealmInfo) a[6], (RealmInfo) a[7]));
(String) a[3], (String) a[4]), (Boolean) a[5], (RealmInfo) a[6], (RealmInfo) a[7], (String) a[8]));
static {
final ConstructingObjectParser<RealmInfo, Void> realmInfoParser = new ConstructingObjectParser<>("realm_info", true,
a -> new RealmInfo((String) a[0], (String) a[1]));
Expand All @@ -69,20 +70,23 @@ public final class AuthenticateResponse {
PARSER.declareBoolean(constructorArg(), ENABLED);
PARSER.declareObject(constructorArg(), realmInfoParser, AUTHENTICATION_REALM);
PARSER.declareObject(constructorArg(), realmInfoParser, LOOKUP_REALM);
PARSER.declareString(constructorArg(), AUTHENTICATION_TYPE);
}

private final User user;
private final boolean enabled;
private final RealmInfo authenticationRealm;
private final RealmInfo lookupRealm;
private final String authenticationType;


public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
RealmInfo lookupRealm) {
RealmInfo lookupRealm, String authenticationType) {
this.user = user;
this.enabled = enabled;
this.authenticationRealm = authenticationRealm;
this.lookupRealm = lookupRealm;
this.authenticationType = authenticationType;
}

/**
Expand Down Expand Up @@ -115,6 +119,10 @@ public RealmInfo getLookupRealm() {
return lookupRealm;
}

public String getAuthenticationType() {
return authenticationType;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand All @@ -123,12 +131,13 @@ public boolean equals(Object o) {
return enabled == that.enabled &&
Objects.equals(user, that.user) &&
Objects.equals(authenticationRealm, that.authenticationRealm) &&
Objects.equals(lookupRealm, that.lookupRealm);
Objects.equals(lookupRealm, that.lookupRealm) &&
Objects.equals(authenticationType, that.authenticationType);
}

@Override
public int hashCode() {
return Objects.hash(user, enabled, authenticationRealm, lookupRealm);
return Objects.hash(user, enabled, authenticationRealm, lookupRealm, authenticationType);
}

public static AuthenticateResponse fromXContent(XContentParser parser) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public void testAuthenticate() throws Exception {

assertThat(authenticateResponse.getUser(), is(putUserRequest.getUser()));
assertThat(authenticateResponse.enabled(), is(true));
assertThat(authenticateResponse.getAuthenticationType(), is("realm"));

// get user
final GetUsersRequest getUsersRequest =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,7 @@ public void testAuthenticate() throws Exception {
final String authenticationRealmType = response.getAuthenticationRealm().getType(); // <4>
final String lookupRealmName = response.getLookupRealm().getName(); // <5>
final String lookupRealmType = response.getLookupRealm().getType(); // <6>
final String authenticationType = response.getAuthenticationType(); // <7>
//end::authenticate-response

assertThat(user.getUsername(), is("test_user"));
Expand All @@ -762,6 +763,7 @@ public void testAuthenticate() throws Exception {
assertThat(authenticationRealmType, is("file"));
assertThat(lookupRealmName, is("default_file"));
assertThat(lookupRealmType, is("file"));
assertThat(authenticationType, is("realm"));
}

{
Expand Down Expand Up @@ -2341,6 +2343,7 @@ public void testDelegatePkiAuthentication() throws Exception {
assertThat(authnRealm, is(notNullValue()));
assertThat(authnRealm.getName(), is("pki1"));
assertThat(authnRealm.getType(), is("pki"));
assertThat(resp.getAuthenticationType(), is("token"));
}

{
Expand Down Expand Up @@ -2384,6 +2387,7 @@ public void onFailure(Exception e) {
assertThat(authnRealm, is(notNullValue()));
assertThat(authnRealm.getName(), is("pki1"));
assertThat(authnRealm.getType(), is("pki"));
assertThat(resp.getAuthenticationType(), is("token"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,11 @@ protected AuthenticateResponse createTestInstance() {
final String authenticationRealmType = randomFrom("file", "native", "ldap", "active_directory", "saml", "kerberos");
final String lookupRealmName = randomAlphaOfLength(5);
final String lookupRealmType = randomFrom("file", "native", "ldap", "active_directory", "saml", "kerberos");
final String authenticationType = randomFrom("realm", "api_key", "token", "anonymous", "internal");
return new AuthenticateResponse(
new User(username, roles, metadata, fullName, email), enabled,
new AuthenticateResponse.RealmInfo(authenticationRealmName, authenticationRealmType),
new AuthenticateResponse.RealmInfo(lookupRealmName, lookupRealmType));
new AuthenticateResponse.RealmInfo(lookupRealmName, lookupRealmType), authenticationType);
}

private void toXContent(AuthenticateResponse response, XContentBuilder builder) throws IOException {
Expand All @@ -103,6 +104,7 @@ private void toXContent(AuthenticateResponse response, XContentBuilder builder)
builder.field(AuthenticateResponse.REALM_NAME.getPreferredName(), response.getLookupRealm().getName());
builder.field(AuthenticateResponse.REALM_TYPE.getPreferredName(), response.getLookupRealm().getType());
builder.endObject();
builder.field(AuthenticateResponse.AUTHENTICATION_TYPE.getPreferredName(), response.getAuthenticationType());
builder.endObject();
}

Expand All @@ -111,48 +113,56 @@ private AuthenticateResponse copy(AuthenticateResponse response) {
final User copyUser = new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail());
return new AuthenticateResponse(copyUser, response.enabled(), response.getAuthenticationRealm(),
response.getLookupRealm());
response.getLookupRealm(), response.getAuthenticationType());
}

private AuthenticateResponse mutate(AuthenticateResponse response) {
final User originalUser = response.getUser();
switch (randomIntBetween(1, 8)) {
switch (randomIntBetween(1, 9)) {
case 1:
return new AuthenticateResponse(new User(originalUser.getUsername() + "wrong", originalUser.getRoles(),
originalUser.getMetadata(), originalUser.getFullName(), originalUser.getEmail()), response.enabled(),
response.getAuthenticationRealm(), response.getLookupRealm());
response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType());
case 2:
final List<String> wrongRoles = new ArrayList<>(originalUser.getRoles());
wrongRoles.add(randomAlphaOfLengthBetween(1, 4));
return new AuthenticateResponse(new User(originalUser.getUsername(), wrongRoles, originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
response.getLookupRealm());
response.getLookupRealm(), response.getAuthenticationType());
case 3:
final Map<String, Object> wrongMetadata = new HashMap<>(originalUser.getMetadata());
wrongMetadata.put("wrong_string", randomAlphaOfLengthBetween(0, 4));
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), wrongMetadata,
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
response.getLookupRealm());
response.getLookupRealm(), response.getAuthenticationType());
case 4:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName() + "wrong", originalUser.getEmail()), response.enabled(),
response.getAuthenticationRealm(), response.getLookupRealm());
response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType());
case 5:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail() + "wrong"), response.enabled(),
response.getAuthenticationRealm(), response.getLookupRealm());
response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType());
case 6:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), !response.enabled(), response.getAuthenticationRealm(),
response.getLookupRealm());
response.getLookupRealm(), response.getAuthenticationType());
case 7:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)));
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)),
response.getAuthenticationType());
case 8:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled(),
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)), response.getLookupRealm());
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)), response.getLookupRealm(),
response.getAuthenticationType());
case 9:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
response.getLookupRealm(),
randomValueOtherThan(response.getAuthenticationType(),
() -> randomFrom("realm", "api_key", "token", "anonymous", "internal")));
}
throw new IllegalStateException("Bad random number");
}
Expand Down
1 change: 1 addition & 0 deletions docs/java-rest/high-level/security/authenticate.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ see {javadoc-client}/security/user/User.html.
<4> `getAuthenticationRealm().getType()` retrieves the type of the realm that authenticated the user.
<5> `getLookupRealm().getName()` retrieves the name of the realm from where the user information is looked up.
<6> `getLookupRealm().getType()` retrieves the type of the realm from where the user information is looked up.
<7> `getAuthenticationType()` retrieves the authentication type of the authenticated user.

[id="{upid}-{api}-async"]
==== Asynchronous Execution
Expand Down
7 changes: 4 additions & 3 deletions x-pack/docs/en/rest-api/security/authenticate.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ The following example output provides information about the "rdeniro" user:
--------------------------------------------------
{
"username": "rdeniro",
"roles": [
"roles": [
"admin"
],
"full_name": null,
Expand All @@ -56,8 +56,9 @@ The following example output provides information about the "rdeniro" user:
"lookup_realm": {
"name" : "file",
"type" : "file"
}
},
"authentication_type": "realm"
}
--------------------------------------------------
// TESTRESPONSE[s/"rdeniro"/"$body.username"/]
// TESTRESPONSE[s/"admin"/"superuser"/]
// TESTRESPONSE[s/"admin"/"superuser"/]
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ public void writeTo(StreamOutput out) throws IOException {
authentication.writeTo(out);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.io.IOException;
import java.util.Base64;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

Expand Down Expand Up @@ -176,6 +177,7 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
builder.field(User.Fields.REALM_TYPE.getPreferredName(), getAuthenticatedBy().getType());
}
builder.endObject();
builder.field(User.Fields.AUTHENTICATION_TYPE.getPreferredName(), getAuthenticationType().name().toLowerCase(Locale.ROOT));
}

@Override
Expand Down Expand Up @@ -261,4 +263,3 @@ public enum AuthenticationType {
INTERNAL
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ public interface Fields {
ParseField LOOKUP_REALM = new ParseField("lookup_realm");
ParseField REALM_TYPE = new ParseField("type");
ParseField REALM_NAME = new ParseField("name");
ParseField AUTHENTICATION_TYPE = new ParseField("authentication_type");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ public void testCreateApiKey() throws Exception{
AuthenticateResponse authResponse = restClient.security().authenticate(RequestOptions.DEFAULT.toBuilder().addHeader("Authorization",
"ApiKey " + base64ApiKeyKeyValue).build());
assertThat(authResponse.getUser().getUsername(), equalTo(SecuritySettingsSource.TEST_SUPERUSER));
assertThat(authResponse.getAuthenticationType(), equalTo("api_key"));

// use the first ApiKey for an unauthorized action
ElasticsearchSecurityException e = expectThrows(ElasticsearchSecurityException.class, () ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,9 @@ public void testCreateThenRefreshAsDifferentUser() throws IOException {
assertNotEquals(refreshResponse.getRefreshToken(), createTokenResponse.getRefreshToken());

AuthenticateResponse response = restClient.security().authenticate(superuserOptions);
;

assertEquals(SecuritySettingsSource.TEST_SUPERUSER, response.getUser().getUsername());
assertEquals("realm", response.getAuthenticationType());

assertAuthenticateWithToken(createTokenResponse.getAccessToken(), SecuritySettingsSource.TEST_USER_NAME);
assertAuthenticateWithToken(refreshResponse.getAccessToken(), SecuritySettingsSource.TEST_USER_NAME);
Expand Down Expand Up @@ -604,6 +605,7 @@ private void assertAuthenticateWithToken(String accessToken, String expectedUser
AuthenticateResponse authResponse = restClient.security().authenticate(RequestOptions.DEFAULT.toBuilder().addHeader("Authorization",
"Bearer " + accessToken).build());
assertThat(authResponse.getUser().getUsername(), equalTo(expectedUser));
assertThat(authResponse.getAuthenticationType(), equalTo("token"));
}

private void assertUnauthorizedToken(String accessToken) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ public void testDelegateThenAuthenticate() throws Exception {
assertThat(authnRealm, is(notNullValue()));
assertThat(authnRealm.getName(), is("pki3"));
assertThat(authnRealm.getType(), is("pki"));
assertThat(resp.getAuthenticationType(), is("token"));
}
}
}
Expand Down Expand Up @@ -205,6 +206,7 @@ public void testTokenInvalidate() throws Exception {
assertThat(authnRealm, is(notNullValue()));
assertThat(authnRealm.getName(), is("pki3"));
assertThat(authnRealm.getType(), is("pki"));
assertThat(resp.getAuthenticationType(), is("token"));
// invalidate
InvalidateTokenRequest invalidateRequest = new InvalidateTokenRequest(token, null, null, null);
optionsBuilder = RequestOptions.DEFAULT.toBuilder();
Expand Down Expand Up @@ -291,6 +293,7 @@ public void testDelegatePkiWithRoleMapping() throws Exception {
assertThat(authnRealm, is(notNullValue()));
assertThat(authnRealm.getName(), is("pki3"));
assertThat(authnRealm.getType(), is("pki"));
assertThat(resp.getAuthenticationType(), is("token"));
// delete role mappings for delegated PKI
restClient.security().deleteRoleMapping(new DeleteRoleMappingRequest("role_by_delegated_user", RefreshPolicy.IMMEDIATE),
testUserOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public void testAuthenticateApi() throws Exception {
assertThat(objectPath.evaluate("authentication_realm.type").toString(), equalTo("file"));
assertThat(objectPath.evaluate("lookup_realm.name").toString(), equalTo("file"));
assertThat(objectPath.evaluate("lookup_realm.type").toString(), equalTo("file"));
assertThat(objectPath.evaluate("authentication_type").toString(), equalTo("realm"));
List<String> roles = objectPath.evaluate("roles");
assertThat(roles.size(), is(1));
assertThat(roles, contains(SecuritySettingsSource.TEST_ROLE));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ teardown:
- match: { username: "authenticate_user" }
- match: { roles.0: "superuser" }
- match: { full_name: "Authenticate User" }
- match: { authentication_type: "realm" }