From 22f67996381d44271cd0032fcd6391d3f786f626 Mon Sep 17 00:00:00 2001 From: YuriyZ Date: Mon, 31 Oct 2022 22:11:47 +0200 Subject: [PATCH] fix(jans-auth-server): native sso - return device secret if device_sso scope is present #2790 https://github.com/JanssenProject/jans/issues/2518 --- .../java/io/jans/as/client/TokenResponse.java | 9 +++++ .../io/jans/as/client/client/Asserter.java | 17 ++++++++ .../assertbuilders/JwtAssertBuilder.java | 11 +++++ .../TokenResponseAssertBuilder.java | 11 ++++- .../server/model/common/ExecutionContext.java | 9 +++++ .../as/server/model/token/IdTokenFactory.java | 6 ++- .../token/ws/rs/TokenExchangeService.java | 12 +++--- .../token/ws/rs/TokenRestWebServiceImpl.java | 6 ++- .../token/ws/rs/TokenExchangeServiceTest.java | 40 +++++++++---------- 9 files changed, 92 insertions(+), 29 deletions(-) diff --git a/jans-auth-server/client/src/main/java/io/jans/as/client/TokenResponse.java b/jans-auth-server/client/src/main/java/io/jans/as/client/TokenResponse.java index 9324868a6e3..5eafd82f934 100644 --- a/jans-auth-server/client/src/main/java/io/jans/as/client/TokenResponse.java +++ b/jans-auth-server/client/src/main/java/io/jans/as/client/TokenResponse.java @@ -30,6 +30,7 @@ public class TokenResponse extends BaseResponseWithErrors 1); } + if (notBlankDsHash) { + assertNotBlank(jwt.getClaims().getClaimAsString("ds_hash"), "ds_hash claim is not present"); + } + if (notNullClaimsAddressdata) { assertNotNullClaim(JwtClaimName.ADDRESS_STREET_ADDRESS); assertNotNullClaim(JwtClaimName.ADDRESS_COUNTRY); diff --git a/jans-auth-server/client/src/test/java/io/jans/as/client/client/assertbuilders/TokenResponseAssertBuilder.java b/jans-auth-server/client/src/test/java/io/jans/as/client/client/assertbuilders/TokenResponseAssertBuilder.java index fff82e2ac8e..7d0e56b0e21 100644 --- a/jans-auth-server/client/src/test/java/io/jans/as/client/client/assertbuilders/TokenResponseAssertBuilder.java +++ b/jans-auth-server/client/src/test/java/io/jans/as/client/client/assertbuilders/TokenResponseAssertBuilder.java @@ -1,9 +1,9 @@ package io.jans.as.client.client.assertbuilders; import io.jans.as.client.TokenResponse; -import io.jans.as.client.client.AssertBuilder; import io.jans.as.model.token.TokenErrorResponseType; +import static io.jans.as.client.client.Asserter.assertNotBlank; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; @@ -12,6 +12,7 @@ public class TokenResponseAssertBuilder extends BaseAssertBuilder { private TokenResponse response; private int status = 200; private boolean notNullRefreshToken; + private boolean notBlankDeviceToken; private boolean notNullIdToken; private boolean notNullScope; private boolean nullRefreshToken; @@ -53,6 +54,11 @@ public TokenResponseAssertBuilder notNullRefreshToken() { return this; } + public TokenResponseAssertBuilder notBlankDeviceToken() { + this.notBlankDeviceToken = true; + return this; + } + public TokenResponseAssertBuilder notNullIdToken() { this.notNullIdToken = true; return this; @@ -89,6 +95,9 @@ public void check() { if (notNullRefreshToken) { assertNotNull(response.getRefreshToken(), "The refresh token is null"); } + if (notBlankDeviceToken) { + assertNotBlank(response.getDeviceToken(), "The device token is blank"); + } } else { assertEquals(response.getStatus(), status, "Unexpected HTTP status response: " + response.getEntity()); assertNotNull(response.getEntity(), "The entity is null"); diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/ExecutionContext.java b/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/ExecutionContext.java index 68f6dca4615..f4b289e6c1a 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/ExecutionContext.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/ExecutionContext.java @@ -46,6 +46,7 @@ public class ExecutionContext { private String dpop; private String certAsPem; + private String deviceSecret; private String nonce; private String state; @@ -71,6 +72,14 @@ public ExecutionContext(HttpServletRequest httpRequest, HttpServletResponse http this.httpResponse = httpResponse; } + public String getDeviceSecret() { + return deviceSecret; + } + + public void setDeviceSecret(String deviceSecret) { + this.deviceSecret = deviceSecret; + } + @NotNull public Map getAttributes() { return attributes; diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/model/token/IdTokenFactory.java b/jans-auth-server/server/src/main/java/io/jans/as/server/model/token/IdTokenFactory.java index 4fe604237dc..fe1cd7a09bf 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/model/token/IdTokenFactory.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/model/token/IdTokenFactory.java @@ -258,7 +258,11 @@ private void addTokenExchangeClaims(JsonWebResponse jwr, ExecutionContext execut return; } - String deviceSecret = executionContext.getHttpRequest().getParameter(DEVICE_SECRET); + String deviceSecret = executionContext.getDeviceSecret(); + if (StringUtils.isBlank(deviceSecret)) { + deviceSecret = executionContext.getHttpRequest().getParameter(DEVICE_SECRET); + } + if (StringUtils.isNotBlank(deviceSecret) && sessionId.getDeviceSecrets().contains(deviceSecret)) { jwr.setClaim("ds_hash", CodeVerifier.s256(deviceSecret)); } diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/token/ws/rs/TokenExchangeService.java b/jans-auth-server/server/src/main/java/io/jans/as/server/token/ws/rs/TokenExchangeService.java index 93c168f2bee..d05667158fa 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/token/ws/rs/TokenExchangeService.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/token/ws/rs/TokenExchangeService.java @@ -172,20 +172,21 @@ public JSONObject processTokenExchange(String scope, Function