From 8549bd70b7d9d5ba9006668e5565791a2253d58d Mon Sep 17 00:00:00 2001 From: Martin Hardselius Date: Fri, 2 Mar 2018 13:08:27 +0100 Subject: [PATCH 1/2] Add pairwise sub support to authorization services Identity token verification will now fetch the user from the session state instead of relying on the sub provided in the token. Also done in KeycloakIdentity. Resolves: KEYCLOAK-6659 --- .../common/KeycloakIdentity.java | 9 +- .../managers/AuthenticationManager.java | 28 ++-- .../testsuite/authz/AuthorizationAPITest.java | 86 +++++++++-- .../testsuite/authz/EntitlementAPITest.java | 138 ++++++++++++++---- .../testsuite/util/ClientBuilder.java | 8 + .../testsuite/util/ProtocolMapperUtil.java | 4 + .../default-keycloak-pairwise.json | 8 + 7 files changed, 229 insertions(+), 52 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/default-keycloak-pairwise.json diff --git a/services/src/main/java/org/keycloak/authorization/common/KeycloakIdentity.java b/services/src/main/java/org/keycloak/authorization/common/KeycloakIdentity.java index 654193d0b8..58962b51d4 100644 --- a/services/src/main/java/org/keycloak/authorization/common/KeycloakIdentity.java +++ b/services/src/main/java/org/keycloak/authorization/common/KeycloakIdentity.java @@ -212,7 +212,7 @@ public class KeycloakIdentity implements Identity { return client==null ? null : client.getId(); } - return this.accessToken.getSubject(); + return this.getUserFromSessionState().getId(); } @Override @@ -237,7 +237,7 @@ public class KeycloakIdentity implements Identity { return false; } - return this.accessToken.getSubject().equals(clientUser.getId()); + return this.getUserFromSessionState().getId().equals(clientUser.getId()); } private ClientModel getTargetClient() { @@ -252,4 +252,9 @@ public class KeycloakIdentity implements Identity { return null; } + + private UserModel getUserFromSessionState() { + UserSessionModel userSession = keycloakSession.sessions().getUserSession(realm, accessToken.getSessionState()); + return userSession.getUser(); + } } diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java index e18b444218..803e778115 100755 --- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java +++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java @@ -1082,24 +1082,28 @@ public class AuthenticationManager { } } - UserModel user = session.users().getUserById(token.getSubject(), realm); - if (user == null || !user.isEnabled() ) { - logger.debug("Unknown user in identity token"); - return null; - } - - int userNotBefore = session.users().getNotBeforeOfUser(realm, user); - if (token.getIssuedAt() < userNotBefore) { - logger.debug("User notBefore newer than token"); - return null; - } - UserSessionModel userSession = session.sessions().getUserSession(realm, token.getSessionState()); + UserModel user = null; + if (userSession != null) { + user = userSession.getUser(); + if (user == null || !user.isEnabled()) { + logger.debug("Unknown user in identity token"); + return null; + } + + int userNotBefore = session.users().getNotBeforeOfUser(realm, user); + if (token.getIssuedAt() < userNotBefore) { + logger.debug("User notBefore newer than token"); + return null; + } + } + if (!isSessionValid(realm, userSession)) { // Check if accessToken was for the offline session. if (!isCookie) { UserSessionModel offlineUserSession = session.sessions().getOfflineUserSession(realm, token.getSessionState()); if (isOfflineSessionValid(realm, offlineUserSession)) { + user = offlineUserSession.getUser(); return new AuthResult(user, offlineUserSession, token); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthorizationAPITest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthorizationAPITest.java index 61d27735c9..37dd1ffe3a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthorizationAPITest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthorizationAPITest.java @@ -53,29 +53,53 @@ import org.keycloak.util.JsonSerialization; */ public class AuthorizationAPITest extends AbstractAuthzTest { + private static final String RESOURCE_SERVER_TEST = "resource-server-test"; + private static final String TEST_CLIENT = "test-client"; + private static final String AUTHZ_CLIENT_CONFIG = "default-keycloak.json"; + private static final String PAIRWISE_RESOURCE_SERVER_TEST = "pairwise-resource-server-test"; + private static final String PAIRWISE_TEST_CLIENT = "test-client-pairwise"; + private static final String PAIRWISE_AUTHZ_CLIENT_CONFIG = "default-keycloak-pairwise.json"; + @Override public void addTestRealms(List testRealms) { testRealms.add(RealmBuilder.create().name("authz-test") .roles(RolesBuilder.create().realmRole(RoleBuilder.create().name("uma_authorization").build())) .user(UserBuilder.create().username("marta").password("password").addRoles("uma_authorization")) .user(UserBuilder.create().username("kolo").password("password")) - .client(ClientBuilder.create().clientId("resource-server-test") + .client(ClientBuilder.create().clientId(RESOURCE_SERVER_TEST) .secret("secret") .authorizationServicesEnabled(true) .redirectUris("http://localhost/resource-server-test") .defaultRoles("uma_protection") .directAccessGrants()) - .client(ClientBuilder.create().clientId("test-client") + .client(ClientBuilder.create().clientId(PAIRWISE_RESOURCE_SERVER_TEST) + .secret("secret") + .authorizationServicesEnabled(true) + .redirectUris("http://localhost/resource-server-test") + .defaultRoles("uma_protection") + .directAccessGrants() + .pairwise("http://pairwise.com")) + .client(ClientBuilder.create().clientId(TEST_CLIENT) .secret("secret") .authorizationServicesEnabled(true) .redirectUris("http://localhost/test-client") .directAccessGrants()) + .client(ClientBuilder.create().clientId(PAIRWISE_TEST_CLIENT) + .secret("secret") + .authorizationServicesEnabled(true) + .redirectUris("http://localhost/test-client") + .directAccessGrants()) .build()); } @Before public void configureAuthorization() throws Exception { - ClientResource client = getClient(getRealm()); + configureAuthorization(RESOURCE_SERVER_TEST); + configureAuthorization(PAIRWISE_RESOURCE_SERVER_TEST); + } + + private void configureAuthorization(String clientId) throws Exception { + ClientResource client = getClient(getRealm(), clientId); AuthorizationResource authorization = client.authorization(); ResourceRepresentation resource = new ResourceRepresentation("Resource A"); @@ -102,7 +126,16 @@ public class AuthorizationAPITest extends AbstractAuthzTest { @Test public void testAccessTokenWithUmaAuthorization() { - AuthzClient authzClient = getAuthzClient(); + testAccessTokenWithUmaAuthorization(AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testAccessTokenWithUmaAuthorizationPairwise() { + testAccessTokenWithUmaAuthorization(PAIRWISE_AUTHZ_CLIENT_CONFIG); + } + + public void testAccessTokenWithUmaAuthorization(String authzConfigFile) { + AuthzClient authzClient = getAuthzClient(authzConfigFile); PermissionRequest request = new PermissionRequest("Resource A"); String ticket = authzClient.protection().permission().create(request).getTicket(); @@ -113,32 +146,63 @@ public class AuthorizationAPITest extends AbstractAuthzTest { @Test public void testResourceServerAsAudience() throws Exception { - AuthzClient authzClient = getAuthzClient(); + testResourceServerAsAudience( + TEST_CLIENT, + RESOURCE_SERVER_TEST, + AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testResourceServerAsAudienceWithPairwiseClient() throws Exception { + testResourceServerAsAudience( + PAIRWISE_TEST_CLIENT, + RESOURCE_SERVER_TEST, + AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testPairwiseResourceServerAsAudience() throws Exception { + testResourceServerAsAudience( + TEST_CLIENT, + PAIRWISE_RESOURCE_SERVER_TEST, + PAIRWISE_AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testPairwiseResourceServerAsAudienceWithPairwiseClient() throws Exception { + testResourceServerAsAudience( + PAIRWISE_TEST_CLIENT, + PAIRWISE_RESOURCE_SERVER_TEST, + PAIRWISE_AUTHZ_CLIENT_CONFIG); + } + + public void testResourceServerAsAudience(String clientId, String resourceServerClientId, String authzConfigFile) throws Exception { + AuthzClient authzClient = getAuthzClient(authzConfigFile); PermissionRequest request = new PermissionRequest(); request.setResourceId("Resource A"); - String accessToken = new OAuthClient().realm("authz-test").clientId("test-client").doGrantAccessTokenRequest("secret", "marta", "password").getAccessToken(); + String accessToken = new OAuthClient().realm("authz-test").clientId(clientId).doGrantAccessTokenRequest("secret", "marta", "password").getAccessToken(); String ticket = authzClient.protection().permission().create(request).getTicket(); AuthorizationResponse response = authzClient.authorization(accessToken).authorize(new AuthorizationRequest(ticket)); assertNotNull(response.getToken()); AccessToken rpt = toAccessToken(response.getToken()); - assertEquals("resource-server-test", rpt.getAudience()[0]); + assertEquals(resourceServerClientId, rpt.getAudience()[0]); } private RealmResource getRealm() throws Exception { return adminClient.realm("authz-test"); } - private ClientResource getClient(RealmResource realm) { + private ClientResource getClient(RealmResource realm, String clientId) { ClientsResource clients = realm.clients(); - return clients.findByClientId("resource-server-test").stream().map(representation -> clients.get(representation.getId())).findFirst().orElseThrow(() -> new RuntimeException("Expected client [resource-server-test]")); + return clients.findByClientId(clientId).stream().map(representation -> clients.get(representation.getId())).findFirst().orElseThrow(() -> new RuntimeException("Expected client [resource-server-test]")); } - private AuthzClient getAuthzClient() { + private AuthzClient getAuthzClient(String configFile) { try { - return AuthzClient.create(JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/default-keycloak.json"), Configuration.class)); + return AuthzClient.create(JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/" + configFile), Configuration.class)); } catch (IOException cause) { throw new RuntimeException("Failed to create authz client", cause); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java index 54bcd2e5bb..a7fab87278 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java @@ -55,6 +55,13 @@ import org.keycloak.util.JsonSerialization; */ public class EntitlementAPITest extends AbstractAuthzTest { + private static final String RESOURCE_SERVER_TEST = "resource-server-test"; + private static final String TEST_CLIENT = "test-client"; + private static final String AUTHZ_CLIENT_CONFIG = "default-keycloak.json"; + private static final String PAIRWISE_RESOURCE_SERVER_TEST = "pairwise-resource-server-test"; + private static final String PAIRWISE_TEST_CLIENT = "test-client-pairwise"; + private static final String PAIRWISE_AUTHZ_CLIENT_CONFIG = "default-keycloak-pairwise.json"; + private AuthzClient authzClient; @Override @@ -63,23 +70,41 @@ public class EntitlementAPITest extends AbstractAuthzTest { .roles(RolesBuilder.create().realmRole(RoleBuilder.create().name("uma_authorization").build())) .user(UserBuilder.create().username("marta").password("password").addRoles("uma_authorization")) .user(UserBuilder.create().username("kolo").password("password")) - .client(ClientBuilder.create().clientId("resource-server-test") - .secret("secret") - .authorizationServicesEnabled(true) - .redirectUris("http://localhost/resource-server-test") - .defaultRoles("uma_protection") - .directAccessGrants()) - .client(ClientBuilder.create().clientId("test-client") - .secret("secret") - .authorizationServicesEnabled(true) - .redirectUris("http://localhost/test-client") - .directAccessGrants()) + .client(ClientBuilder.create().clientId(RESOURCE_SERVER_TEST) + .secret("secret") + .authorizationServicesEnabled(true) + .redirectUris("http://localhost/resource-server-test") + .defaultRoles("uma_protection") + .directAccessGrants()) + .client(ClientBuilder.create().clientId(PAIRWISE_RESOURCE_SERVER_TEST) + .secret("secret") + .authorizationServicesEnabled(true) + .redirectUris("http://localhost/resource-server-test") + .defaultRoles("uma_protection") + .pairwise("http://pairwise.com") + .directAccessGrants()) + .client(ClientBuilder.create().clientId(TEST_CLIENT) + .secret("secret") + .authorizationServicesEnabled(true) + .redirectUris("http://localhost/test-client") + .directAccessGrants()) + .client(ClientBuilder.create().clientId(PAIRWISE_TEST_CLIENT) + .secret("secret") + .authorizationServicesEnabled(true) + .redirectUris("http://localhost/test-client") + .pairwise("http://pairwise.com") + .directAccessGrants()) .build()); } @Before public void configureAuthorization() throws Exception { - ClientResource client = getClient(getRealm()); + configureAuthorization(RESOURCE_SERVER_TEST); + configureAuthorization(PAIRWISE_RESOURCE_SERVER_TEST); + } + + public void configureAuthorization(String clientId) throws Exception { + ClientResource client = getClient(getRealm(), clientId); AuthorizationResource authorization = client.authorization(); JSPolicyRepresentation policy = new JSPolicyRepresentation(); @@ -106,6 +131,15 @@ public class EntitlementAPITest extends AbstractAuthzTest { @Test public void testRptRequestWithoutResourceName() { + testRptRequestWithoutResourceName(AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testRptRequestWithoutResourceNamePairwise() { + testRptRequestWithoutResourceName(PAIRWISE_AUTHZ_CLIENT_CONFIG); + } + + public void testRptRequestWithoutResourceName(String configFile) { Metadata metadata = new Metadata(); metadata.setIncludeResourceName(false); @@ -116,32 +150,51 @@ public class EntitlementAPITest extends AbstractAuthzTest { request.setMetadata(metadata); request.addPermission("Resource 1"); - return getAuthzClient().authorization("marta", "password").authorize(request); + return getAuthzClient(configFile).authorization("marta", "password").authorize(request); }); } @Test public void testRptRequestWithResourceName() { + testRptRequestWithResourceName(AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testRptRequestWithResourceNamePairwise() { + testRptRequestWithResourceName(PAIRWISE_AUTHZ_CLIENT_CONFIG); + } + + + public void testRptRequestWithResourceName(String configFile) { Metadata metadata = new Metadata(); metadata.setIncludeResourceName(true); - assertResponse(metadata, () -> getAuthzClient().authorization("marta", "password").authorize()); + assertResponse(metadata, () -> getAuthzClient(configFile).authorization("marta", "password").authorize()); AuthorizationRequest request = new AuthorizationRequest(); request.setMetadata(metadata); request.addPermission("Resource 13"); - assertResponse(metadata, () -> getAuthzClient().authorization("marta", "password").authorize(request)); + assertResponse(metadata, () -> getAuthzClient(configFile).authorization("marta", "password").authorize(request)); request.setMetadata(null); - assertResponse(metadata, () -> getAuthzClient().authorization("marta", "password").authorize(request)); + assertResponse(metadata, () -> getAuthzClient(configFile).authorization("marta", "password").authorize(request)); } @Test public void testPermissionLimit() { + testPermissionLimit(AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testPermissionLimitPairwise() { + testPermissionLimit(PAIRWISE_AUTHZ_CLIENT_CONFIG); + } + + public void testPermissionLimit(String configFile) { AuthorizationRequest request = new AuthorizationRequest(); for (int i = 1; i <= 10; i++) { @@ -154,7 +207,7 @@ public class EntitlementAPITest extends AbstractAuthzTest { request.setMetadata(metadata); - AuthorizationResponse response = getAuthzClient().authorization("marta", "password").authorize(request); + AuthorizationResponse response = getAuthzClient(configFile).authorization("marta", "password").authorize(request); AccessToken rpt = toAccessToken(response.getToken()); List permissions = rpt.getAuthorization().getPermissions(); @@ -174,7 +227,7 @@ public class EntitlementAPITest extends AbstractAuthzTest { request.setMetadata(metadata); request.setRpt(response.getToken()); - response = getAuthzClient().authorization("marta", "password").authorize(request); + response = getAuthzClient(configFile).authorization("marta", "password").authorize(request); rpt = toAccessToken(response.getToken()); permissions = rpt.getAuthorization().getPermissions(); @@ -198,7 +251,7 @@ public class EntitlementAPITest extends AbstractAuthzTest { request.setMetadata(metadata); request.setRpt(response.getToken()); - response = getAuthzClient().authorization("marta", "password").authorize(request); + response = getAuthzClient(configFile).authorization("marta", "password").authorize(request); rpt = toAccessToken(response.getToken()); permissions = rpt.getAuthorization().getPermissions(); @@ -221,7 +274,7 @@ public class EntitlementAPITest extends AbstractAuthzTest { request.setMetadata(metadata); request.setRpt(response.getToken()); - response = getAuthzClient().authorization("marta", "password").authorize(request); + response = getAuthzClient(configFile).authorization("marta", "password").authorize(request); rpt = toAccessToken(response.getToken()); permissions = rpt.getAuthorization().getPermissions(); @@ -236,15 +289,46 @@ public class EntitlementAPITest extends AbstractAuthzTest { @Test public void testResourceServerAsAudience() throws Exception { + testResourceServerAsAudience( + TEST_CLIENT, + RESOURCE_SERVER_TEST, + AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testResourceServerAsAudienceWithPairwiseClient() throws Exception { + testResourceServerAsAudience( + PAIRWISE_TEST_CLIENT, + RESOURCE_SERVER_TEST, + AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testPairwiseResourceServerAsAudience() throws Exception { + testResourceServerAsAudience( + TEST_CLIENT, + PAIRWISE_RESOURCE_SERVER_TEST, + PAIRWISE_AUTHZ_CLIENT_CONFIG); + } + + @Test + public void testPairwiseResourceServerAsAudienceWithPairwiseClient() throws Exception { + testResourceServerAsAudience( + PAIRWISE_TEST_CLIENT, + PAIRWISE_RESOURCE_SERVER_TEST, + PAIRWISE_AUTHZ_CLIENT_CONFIG); + } + + public void testResourceServerAsAudience(String testClientId, String resourceServerClientId, String configFile) throws Exception { AuthorizationRequest request = new AuthorizationRequest(); request.addPermission("Resource 1"); - String accessToken = new OAuthClient().realm("authz-test").clientId("test-client").doGrantAccessTokenRequest("secret", "marta", "password").getAccessToken(); - AuthorizationResponse response = getAuthzClient().authorization(accessToken).authorize(request); + String accessToken = new OAuthClient().realm("authz-test").clientId(testClientId).doGrantAccessTokenRequest("secret", "marta", "password").getAccessToken(); + AuthorizationResponse response = getAuthzClient(configFile).authorization(accessToken).authorize(request); AccessToken rpt = toAccessToken(response.getToken()); - assertEquals("resource-server-test", rpt.getAudience()[0]); + assertEquals(resourceServerClientId, rpt.getAudience()[0]); } private void assertResponse(Metadata metadata, Supplier responseSupplier) { @@ -268,15 +352,15 @@ public class EntitlementAPITest extends AbstractAuthzTest { return adminClient.realm("authz-test"); } - private ClientResource getClient(RealmResource realm) { + private ClientResource getClient(RealmResource realm, String clientId) { ClientsResource clients = realm.clients(); - return clients.findByClientId("resource-server-test").stream().map(representation -> clients.get(representation.getId())).findFirst().orElseThrow(() -> new RuntimeException("Expected client [resource-server-test]")); + return clients.findByClientId(clientId).stream().map(representation -> clients.get(representation.getId())).findFirst().orElseThrow(() -> new RuntimeException("Expected client [resource-server-test]")); } - private AuthzClient getAuthzClient() { + private AuthzClient getAuthzClient(String configFile) { if (authzClient == null) { try { - authzClient = AuthzClient.create(JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/default-keycloak.json"), Configuration.class)); + authzClient = AuthzClient.create(JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/" + configFile), Configuration.class)); } catch (IOException cause) { throw new RuntimeException("Failed to create authz client", cause); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java index 870d0599b1..3fef22aa12 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientBuilder.java @@ -198,4 +198,12 @@ public class ClientBuilder { rep.getProtocolMappers().addAll(Arrays.asList(mappers)); return this; } + + public ClientBuilder pairwise(String sectorIdentifierUri, String salt) { + return protocolMapper(ProtocolMapperUtil.createPairwiseMapper(sectorIdentifierUri, salt)); + } + + public ClientBuilder pairwise(String sectorIdentifierUri) { + return protocolMapper(ProtocolMapperUtil.createPairwiseMapper(sectorIdentifierUri, null)); + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ProtocolMapperUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ProtocolMapperUtil.java index 17e0eb3dc2..18b787210a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ProtocolMapperUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ProtocolMapperUtil.java @@ -6,6 +6,7 @@ import org.keycloak.protocol.oidc.mappers.AddressMapper; import org.keycloak.protocol.oidc.mappers.HardcodedClaim; import org.keycloak.protocol.oidc.mappers.HardcodedRole; import org.keycloak.protocol.oidc.mappers.RoleNameMapper; +import org.keycloak.protocol.oidc.mappers.SHA256PairwiseSubMapper; import org.keycloak.protocol.oidc.mappers.ScriptBasedOIDCProtocolMapper; import org.keycloak.protocol.oidc.mappers.UserAttributeMapper; import org.keycloak.protocol.oidc.mappers.UserClientRoleMappingMapper; @@ -164,4 +165,7 @@ public class ProtocolMapperUtil { ); } + public static ProtocolMapperRepresentation createPairwiseMapper(String sectorIdentifierUri, String salt) { + return SHA256PairwiseSubMapper.createPairwiseMapper(sectorIdentifierUri, salt); + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/default-keycloak-pairwise.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/default-keycloak-pairwise.json new file mode 100644 index 0000000000..fbd7c14613 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/default-keycloak-pairwise.json @@ -0,0 +1,8 @@ +{ + "realm": "authz-test", + "auth-server-url" : "http://localhost:8180/auth", + "resource" : "pairwise-resource-server-test", + "credentials": { + "secret": "secret" + } +} \ No newline at end of file From e2bec73011d756ed616749ec1248113d68f0869b Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Fri, 2 Mar 2018 12:29:07 -0500 Subject: [PATCH 2/2] KEYCLOAK-6336 --- .../messages/admin-messages_en.properties | 2 ++ .../theme/base/admin/resources/js/app.js | 6 +++++ .../admin/resources/js/controllers/clients.js | 11 +++++++- .../resources/partials/client-detail.html | 26 +++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties index aa01891496..c384b13b21 100644 --- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties +++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties @@ -940,6 +940,8 @@ no-required-actions-configured=No required actions configured defaults-to-id=Defaults to id flows=Flows bindings=Bindings +client-flow-bindings=Authentication Flow Overrides +client-flow-bindings.tooltip=Override realm authentication flow bindings. required-actions=Required Actions password-policy=Password Policy otp-policy=OTP Policy diff --git a/themes/src/main/resources/theme/base/admin/resources/js/app.js b/themes/src/main/resources/theme/base/admin/resources/js/app.js index 3c1f0864b1..b76e18fefe 100755 --- a/themes/src/main/resources/theme/base/admin/resources/js/app.js +++ b/themes/src/main/resources/theme/base/admin/resources/js/app.js @@ -1332,6 +1332,9 @@ module.config([ '$routeProvider', function($routeProvider) { client : function() { return {}; }, + flows : function(AuthenticationFlowsLoader) { + return AuthenticationFlowsLoader(); + }, serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); } @@ -1353,6 +1356,9 @@ module.config([ '$routeProvider', function($routeProvider) { client : function(ClientLoader) { return ClientLoader(); }, + flows : function(AuthenticationFlowsLoader) { + return AuthenticationFlowsLoader(); + }, serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); } diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js index d679508cb2..632ef2c664 100755 --- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js +++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js @@ -829,7 +829,16 @@ module.controller('ClientInstallationCtrl', function($scope, realm, client, serv } }); -module.controller('ClientDetailCtrl', function($scope, realm, client, templates, $route, serverInfo, Client, ClientDescriptionConverter, Components, ClientStorageOperations, $location, $modal, Dialog, Notifications) { +module.controller('ClientDetailCtrl', function($scope, realm, client, templates, flows, $route, serverInfo, Client, ClientDescriptionConverter, Components, ClientStorageOperations, $location, $modal, Dialog, Notifications) { + $scope.flows = []; + $scope.clientFlows = []; + for (var i=0 ; i +
+ {{:: 'client-flow-bindings' | translate}} {{:: 'client-flow-bindings.tooltip' | translate}} +
+ +
+
+ +
+
+ {{:: 'browser-flow.tooltip' | translate}} +
+
+ +
+
+ +
+
+ {{:: 'direct-grant-flow.tooltip' | translate}} +
+
+ + +