Browse Source

Adds realm name OIDC `_security/oidc/prepare` and `_security/oidc/authenticate` APIs responses (#64966)

* This change adds realm name of the realm used to perform authentication to the responses of _security/oidc/authenticate and _security/oidc/authenticate APIs

Resolves #53161

* This change adds realm name of the realm used to perform authentication to the responses of _security/oidc/authenticate and _security/oidc/authenticate APIs

Resolves #53161

* This change adds realm name of the realm used to perform authentication to the responses of _security/oidc/authenticate and _security/oidc/authenticate APIs

Resolves #53161

* This change adds realm name of the realm used to perform authentication to the responses of _security/oidc/authenticate and _security/oidc/authenticate APIs

Resolves #53161

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Lyudmila Fokina 4 years ago
parent
commit
a3063889a2

+ 1 - 1
x-pack/docs/en/rest-api/security/oidc-authenticate-api.asciidoc

@@ -58,7 +58,7 @@ be used to authenticate this. Useful when multiple realms have been defined.
 
 
 The following example request exchanges the response that was returned from the
 The following example request exchanges the response that was returned from the
 OpenID Connect Provider after a successful authentication, for an {es} access
 OpenID Connect Provider after a successful authentication, for an {es} access
-token and refresh token to be used in subsequent requests. This example is from 
+token and refresh token to be used in subsequent requests. This example is from
 an authentication that uses the authorization code grant flow.
 an authentication that uses the authorization code grant flow.
 
 
 [source,console]
 [source,console]

+ 11 - 8
x-pack/docs/en/rest-api/security/oidc-prepare-authentication-api.asciidoc

@@ -3,7 +3,7 @@
 === OpenID Connect Prepare Authentication API
 === OpenID Connect Prepare Authentication API
 
 
 Creates an oAuth 2.0 authentication request as a URL string based on the
 Creates an oAuth 2.0 authentication request as a URL string based on the
-configuration of the respective OpenID Connect authentication realm in {es}. 
+configuration of the respective OpenID Connect authentication realm in {es}.
 
 
 [[security-api-oidc-prepare-authentication-request]]
 [[security-api-oidc-prepare-authentication-request]]
 ==== {api-request-title}
 ==== {api-request-title}
@@ -16,13 +16,13 @@ configuration of the respective OpenID Connect authentication realm in {es}.
 [[security-api-oidc-prepare-authentication-desc]]
 [[security-api-oidc-prepare-authentication-desc]]
 ==== {api-description-title}
 ==== {api-description-title}
 
 
-The response of this API is a URL pointing to the Authorization Endpoint of the 
-configured OpenID Connect Provider and can be used to redirect the browser of 
+The response of this API is a URL pointing to the Authorization Endpoint of the
+configured OpenID Connect Provider and can be used to redirect the browser of
 the user in order to continue the authentication process.
 the user in order to continue the authentication process.
 
 
 {es} exposes all the necessary OpenID Connect related functionality via the
 {es} exposes all the necessary OpenID Connect related functionality via the
 OpenID Connect APIs. These APIs are used internally by {kib} in order to provide
 OpenID Connect APIs. These APIs are used internally by {kib} in order to provide
-OpenID Connect based authentication, but can also be used by other, custom web 
+OpenID Connect based authentication, but can also be used by other, custom web
 applications or other clients. See also
 applications or other clients. See also
 <<security-api-oidc-authenticate,OpenID Connect authenticate API>>
 <<security-api-oidc-authenticate,OpenID Connect authenticate API>>
 and <<security-api-oidc-logout,OpenID Connect logout API>>.
 and <<security-api-oidc-logout,OpenID Connect logout API>>.
@@ -81,7 +81,8 @@ the Authentication Request, as HTTP GET parameters:
 {
 {
   "redirect" : "http://127.0.0.1:8080/c2id-login?scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I&nonce=WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM&client_id=elasticsearch-rp",
   "redirect" : "http://127.0.0.1:8080/c2id-login?scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I&nonce=WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM&client_id=elasticsearch-rp",
   "state" : "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
   "state" : "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
-  "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM"
+  "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM",
+  "realm" : "oidc1"
 }
 }
 --------------------------------------------------
 --------------------------------------------------
 // TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/\$\{body.state\}/]
 // TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/\$\{body.state\}/]
@@ -109,7 +110,8 @@ the Authentication Request, as HTTP GET parameters:
 {
 {
   "redirect" : "http://127.0.0.1:8080/c2id-login?scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=lGYK0EcSLjqH6pkT5EVZjC6eIW5YCGgywj2sxROO&nonce=zOBXLJGUooRrbLbQk5YCcyC8AXw3iloynvluYhZ5&client_id=elasticsearch-rp",
   "redirect" : "http://127.0.0.1:8080/c2id-login?scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=lGYK0EcSLjqH6pkT5EVZjC6eIW5YCGgywj2sxROO&nonce=zOBXLJGUooRrbLbQk5YCcyC8AXw3iloynvluYhZ5&client_id=elasticsearch-rp",
   "state" : "lGYK0EcSLjqH6pkT5EVZjC6eIW5YCGgywj2sxROO",
   "state" : "lGYK0EcSLjqH6pkT5EVZjC6eIW5YCGgywj2sxROO",
-  "nonce" : "zOBXLJGUooRrbLbQk5YCcyC8AXw3iloynvluYhZ5"
+  "nonce" : "zOBXLJGUooRrbLbQk5YCcyC8AXw3iloynvluYhZ5",
+  "realm" : "oidc1"
 }
 }
 --------------------------------------------------
 --------------------------------------------------
 
 
@@ -134,8 +136,9 @@ the Authentication Request, as HTTP GET parameters:
 {
 {
   "redirect" : "http://127.0.0.1:8080/c2id-login?login_hint=this_is_an_opaque_string&scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I&nonce=WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM&client_id=elasticsearch-rp",
   "redirect" : "http://127.0.0.1:8080/c2id-login?login_hint=this_is_an_opaque_string&scope=openid&response_type=id_token&redirect_uri=https%3A%2F%2Fmy.fantastic.rp%2Fcb&state=4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I&nonce=WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM&client_id=elasticsearch-rp",
   "state" : "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
   "state" : "4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I",
-  "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM"
+  "nonce" : "WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM",
+  "realm" : "oidc1"
 }
 }
 --------------------------------------------------
 --------------------------------------------------
 // TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/\$\{body.state\}/]
 // TESTRESPONSE[s/4dbrihtIAt3wBTwo6DxK-vdk-sSyDBV8Yf0AjdkdT5I/\$\{body.state\}/]
-// TESTRESPONSE[s/WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM/\$\{body.nonce\}/]
+// TESTRESPONSE[s/WaBPH0KqPVdG5HHdSxPRjfoZbXMCicm5v1OiAj0DUFM/\$\{body.nonce\}/]

+ 22 - 2
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/action/oidc/OpenIdConnectPrepareAuthenticationResponse.java

@@ -5,6 +5,7 @@
  */
  */
 package org.elasticsearch.xpack.core.security.action.oidc;
 package org.elasticsearch.xpack.core.security.action.oidc;
 
 
+import org.elasticsearch.Version;
 import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.io.stream.StreamOutput;
@@ -28,11 +29,16 @@ public class OpenIdConnectPrepareAuthenticationResponse extends ActionResponse i
      * String value used to associate a Client session with an ID Token, and to mitigate replay attacks.
      * String value used to associate a Client session with an ID Token, and to mitigate replay attacks.
      */
      */
     private String nonce;
     private String nonce;
+    /*
+     * String value: name of the realm used to perform authentication.
+     */
+    private String realmName;
 
 
-    public OpenIdConnectPrepareAuthenticationResponse(String authorizationEndpointUrl, String state, String nonce) {
+    public OpenIdConnectPrepareAuthenticationResponse(String authorizationEndpointUrl, String state, String nonce, String realmName) {
         this.authenticationRequestUrl = authorizationEndpointUrl;
         this.authenticationRequestUrl = authorizationEndpointUrl;
         this.state = state;
         this.state = state;
         this.nonce = nonce;
         this.nonce = nonce;
+        this.realmName = realmName;
     }
     }
 
 
     public OpenIdConnectPrepareAuthenticationResponse(StreamInput in) throws IOException {
     public OpenIdConnectPrepareAuthenticationResponse(StreamInput in) throws IOException {
@@ -40,6 +46,9 @@ public class OpenIdConnectPrepareAuthenticationResponse extends ActionResponse i
         authenticationRequestUrl = in.readString();
         authenticationRequestUrl = in.readString();
         state = in.readString();
         state = in.readString();
         nonce = in.readString();
         nonce = in.readString();
+        if (in.getVersion().onOrAfter(Version.V_7_11_0)) {
+            realmName = in.readString();
+        }
     }
     }
 
 
     public String getAuthenticationRequestUrl() {
     public String getAuthenticationRequestUrl() {
@@ -54,15 +63,23 @@ public class OpenIdConnectPrepareAuthenticationResponse extends ActionResponse i
         return nonce;
         return nonce;
     }
     }
 
 
+    public String getRealmName() {
+        return realmName;
+    }
+
     @Override
     @Override
     public void writeTo(StreamOutput out) throws IOException {
     public void writeTo(StreamOutput out) throws IOException {
         out.writeString(authenticationRequestUrl);
         out.writeString(authenticationRequestUrl);
         out.writeString(state);
         out.writeString(state);
         out.writeString(nonce);
         out.writeString(nonce);
+        if (out.getVersion().onOrAfter(Version.V_7_11_0)) {
+            out.writeString(realmName);
+        }
     }
     }
 
 
     public String toString() {
     public String toString() {
-        return "{authenticationRequestUrl=" + authenticationRequestUrl + ", state=" + state + ", nonce=" + nonce + "}";
+        return "{authenticationRequestUrl=" + authenticationRequestUrl + ", state=" + state + ", nonce="
+            + nonce + ", realmName" + realmName + "}";
     }
     }
 
 
     @Override
     @Override
@@ -71,6 +88,9 @@ public class OpenIdConnectPrepareAuthenticationResponse extends ActionResponse i
         builder.field("redirect", authenticationRequestUrl);
         builder.field("redirect", authenticationRequestUrl);
         builder.field("state", state);
         builder.field("state", state);
         builder.field("nonce", nonce);
         builder.field("nonce", nonce);
+        if(realmName != null){
+            builder.field("realm", realmName);
+        }
         builder.endObject();
         builder.endObject();
         return builder;
         return builder;
     }
     }

+ 1 - 1
x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectRealm.java

@@ -363,7 +363,7 @@ public class OpenIdConnectRealm extends Realm implements Releasable {
             builder.loginHint(loginHint);
             builder.loginHint(loginHint);
         }
         }
         return new OpenIdConnectPrepareAuthenticationResponse(builder.build().toURI().toString(),
         return new OpenIdConnectPrepareAuthenticationResponse(builder.build().toURI().toString(),
-            state.getValue(), nonce.getValue());
+            state.getValue(), nonce.getValue(), this.name());
     }
     }
 
 
     public boolean isIssuerValid(String issuer) {
     public boolean isIssuerValid(String issuer) {

+ 5 - 0
x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectRealmTests.java

@@ -269,6 +269,7 @@ public class OpenIdConnectRealmTests extends OpenIdConnectTestCase {
         assertThat(response.getAuthenticationRequestUrl(),
         assertThat(response.getAuthenticationRequestUrl(),
             equalTo("https://op.example.com/login?scope=scope1+scope2+openid&response_type=code" +
             equalTo("https://op.example.com/login?scope=scope1+scope2+openid&response_type=code" +
                 "&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" + state + "&nonce=" + nonce + "&client_id=rp-my"));
                 "&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" + state + "&nonce=" + nonce + "&client_id=rp-my"));
+        assertThat(response.getRealmName(), equalTo(REALM_NAME));
     }
     }
 
 
     public void testBuildingAuthenticationRequest() {
     public void testBuildingAuthenticationRequest() {
@@ -292,6 +293,7 @@ public class OpenIdConnectRealmTests extends OpenIdConnectTestCase {
         assertThat(response.getAuthenticationRequestUrl(),
         assertThat(response.getAuthenticationRequestUrl(),
             equalTo("https://op.example.com/login?scope=openid+scope1+scope2&response_type=code" +
             equalTo("https://op.example.com/login?scope=openid+scope1+scope2&response_type=code" +
                 "&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" + state + "&nonce=" + nonce + "&client_id=rp-my"));
                 "&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" + state + "&nonce=" + nonce + "&client_id=rp-my"));
+        assertThat(response.getRealmName(), equalTo(REALM_NAME));
     }
     }
 
 
     public void testBuilidingAuthenticationRequestWithDefaultScope() {
     public void testBuilidingAuthenticationRequestWithDefaultScope() {
@@ -313,6 +315,7 @@ public class OpenIdConnectRealmTests extends OpenIdConnectTestCase {
         final String nonce = response.getNonce();
         final String nonce = response.getNonce();
         assertThat(response.getAuthenticationRequestUrl(), equalTo("https://op.example.com/login?scope=openid&response_type=code" +
         assertThat(response.getAuthenticationRequestUrl(), equalTo("https://op.example.com/login?scope=openid&response_type=code" +
             "&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" + state + "&nonce=" + nonce + "&client_id=rp-my"));
             "&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" + state + "&nonce=" + nonce + "&client_id=rp-my"));
+        assertThat(response.getRealmName(), equalTo(REALM_NAME));
     }
     }
 
 
     public void testBuildLogoutResponse() throws Exception {
     public void testBuildLogoutResponse() throws Exception {
@@ -370,6 +373,7 @@ public class OpenIdConnectRealmTests extends OpenIdConnectTestCase {
 
 
         assertThat(response.getAuthenticationRequestUrl(), equalTo("https://op.example.com/login?scope=openid&response_type=code" +
         assertThat(response.getAuthenticationRequestUrl(), equalTo("https://op.example.com/login?scope=openid&response_type=code" +
             "&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" + state + "&nonce=" + nonce + "&client_id=rp-my"));
             "&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" + state + "&nonce=" + nonce + "&client_id=rp-my"));
+        assertThat(response.getRealmName(), equalTo(REALM_NAME));
     }
     }
 
 
     public void testBuildingAuthenticationRequestWithLoginHint() {
     public void testBuildingAuthenticationRequestWithLoginHint() {
@@ -394,6 +398,7 @@ public class OpenIdConnectRealmTests extends OpenIdConnectTestCase {
         assertThat(response.getAuthenticationRequestUrl(), equalTo("https://op.example.com/login?login_hint=" + thehint +
         assertThat(response.getAuthenticationRequestUrl(), equalTo("https://op.example.com/login?login_hint=" + thehint +
             "&scope=openid&response_type=code&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" +
             "&scope=openid&response_type=code&redirect_uri=https%3A%2F%2Frp.my.com%2Fcb&state=" +
             state + "&nonce=" + nonce + "&client_id=rp-my"));
             state + "&nonce=" + nonce + "&client_id=rp-my"));
+        assertThat(response.getRealmName(), equalTo(REALM_NAME));
     }
     }
 
 
     private AuthenticationResult authenticateWithOidc(String principal, UserRoleMapper roleMapper, boolean notPopulateMetadata,
     private AuthenticationResult authenticateWithOidc(String principal, UserRoleMapper roleMapper, boolean notPopulateMetadata,