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
This commit is contained in:
Martin Hardselius 2018-03-02 13:08:27 +01:00
parent 9b1275f182
commit 8549bd70b7
7 changed files with 229 additions and 52 deletions

View file

@ -212,7 +212,7 @@ public class KeycloakIdentity implements Identity {
return client==null ? null : client.getId(); return client==null ? null : client.getId();
} }
return this.accessToken.getSubject(); return this.getUserFromSessionState().getId();
} }
@Override @Override
@ -237,7 +237,7 @@ public class KeycloakIdentity implements Identity {
return false; return false;
} }
return this.accessToken.getSubject().equals(clientUser.getId()); return this.getUserFromSessionState().getId().equals(clientUser.getId());
} }
private ClientModel getTargetClient() { private ClientModel getTargetClient() {
@ -252,4 +252,9 @@ public class KeycloakIdentity implements Identity {
return null; return null;
} }
private UserModel getUserFromSessionState() {
UserSessionModel userSession = keycloakSession.sessions().getUserSession(realm, accessToken.getSessionState());
return userSession.getUser();
}
} }

View file

@ -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()); 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)) { if (!isSessionValid(realm, userSession)) {
// Check if accessToken was for the offline session. // Check if accessToken was for the offline session.
if (!isCookie) { if (!isCookie) {
UserSessionModel offlineUserSession = session.sessions().getOfflineUserSession(realm, token.getSessionState()); UserSessionModel offlineUserSession = session.sessions().getOfflineUserSession(realm, token.getSessionState());
if (isOfflineSessionValid(realm, offlineUserSession)) { if (isOfflineSessionValid(realm, offlineUserSession)) {
user = offlineUserSession.getUser();
return new AuthResult(user, offlineUserSession, token); return new AuthResult(user, offlineUserSession, token);
} }
} }

View file

@ -53,29 +53,53 @@ import org.keycloak.util.JsonSerialization;
*/ */
public class AuthorizationAPITest extends AbstractAuthzTest { 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 @Override
public void addTestRealms(List<RealmRepresentation> testRealms) { public void addTestRealms(List<RealmRepresentation> testRealms) {
testRealms.add(RealmBuilder.create().name("authz-test") testRealms.add(RealmBuilder.create().name("authz-test")
.roles(RolesBuilder.create().realmRole(RoleBuilder.create().name("uma_authorization").build())) .roles(RolesBuilder.create().realmRole(RoleBuilder.create().name("uma_authorization").build()))
.user(UserBuilder.create().username("marta").password("password").addRoles("uma_authorization")) .user(UserBuilder.create().username("marta").password("password").addRoles("uma_authorization"))
.user(UserBuilder.create().username("kolo").password("password")) .user(UserBuilder.create().username("kolo").password("password"))
.client(ClientBuilder.create().clientId("resource-server-test") .client(ClientBuilder.create().clientId(RESOURCE_SERVER_TEST)
.secret("secret") .secret("secret")
.authorizationServicesEnabled(true) .authorizationServicesEnabled(true)
.redirectUris("http://localhost/resource-server-test") .redirectUris("http://localhost/resource-server-test")
.defaultRoles("uma_protection") .defaultRoles("uma_protection")
.directAccessGrants()) .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") .secret("secret")
.authorizationServicesEnabled(true) .authorizationServicesEnabled(true)
.redirectUris("http://localhost/test-client") .redirectUris("http://localhost/test-client")
.directAccessGrants()) .directAccessGrants())
.client(ClientBuilder.create().clientId(PAIRWISE_TEST_CLIENT)
.secret("secret")
.authorizationServicesEnabled(true)
.redirectUris("http://localhost/test-client")
.directAccessGrants())
.build()); .build());
} }
@Before @Before
public void configureAuthorization() throws Exception { 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(); AuthorizationResource authorization = client.authorization();
ResourceRepresentation resource = new ResourceRepresentation("Resource A"); ResourceRepresentation resource = new ResourceRepresentation("Resource A");
@ -102,7 +126,16 @@ public class AuthorizationAPITest extends AbstractAuthzTest {
@Test @Test
public void testAccessTokenWithUmaAuthorization() { 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"); PermissionRequest request = new PermissionRequest("Resource A");
String ticket = authzClient.protection().permission().create(request).getTicket(); String ticket = authzClient.protection().permission().create(request).getTicket();
@ -113,32 +146,63 @@ public class AuthorizationAPITest extends AbstractAuthzTest {
@Test @Test
public void testResourceServerAsAudience() throws Exception { 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(); PermissionRequest request = new PermissionRequest();
request.setResourceId("Resource A"); 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(); String ticket = authzClient.protection().permission().create(request).getTicket();
AuthorizationResponse response = authzClient.authorization(accessToken).authorize(new AuthorizationRequest(ticket)); AuthorizationResponse response = authzClient.authorization(accessToken).authorize(new AuthorizationRequest(ticket));
assertNotNull(response.getToken()); assertNotNull(response.getToken());
AccessToken rpt = toAccessToken(response.getToken()); AccessToken rpt = toAccessToken(response.getToken());
assertEquals("resource-server-test", rpt.getAudience()[0]); assertEquals(resourceServerClientId, rpt.getAudience()[0]);
} }
private RealmResource getRealm() throws Exception { private RealmResource getRealm() throws Exception {
return adminClient.realm("authz-test"); return adminClient.realm("authz-test");
} }
private ClientResource getClient(RealmResource realm) { private ClientResource getClient(RealmResource realm, String clientId) {
ClientsResource clients = realm.clients(); 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 { 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) { } catch (IOException cause) {
throw new RuntimeException("Failed to create authz client", cause); throw new RuntimeException("Failed to create authz client", cause);
} }

View file

@ -55,6 +55,13 @@ import org.keycloak.util.JsonSerialization;
*/ */
public class EntitlementAPITest extends AbstractAuthzTest { 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; private AuthzClient authzClient;
@Override @Override
@ -63,23 +70,41 @@ public class EntitlementAPITest extends AbstractAuthzTest {
.roles(RolesBuilder.create().realmRole(RoleBuilder.create().name("uma_authorization").build())) .roles(RolesBuilder.create().realmRole(RoleBuilder.create().name("uma_authorization").build()))
.user(UserBuilder.create().username("marta").password("password").addRoles("uma_authorization")) .user(UserBuilder.create().username("marta").password("password").addRoles("uma_authorization"))
.user(UserBuilder.create().username("kolo").password("password")) .user(UserBuilder.create().username("kolo").password("password"))
.client(ClientBuilder.create().clientId("resource-server-test") .client(ClientBuilder.create().clientId(RESOURCE_SERVER_TEST)
.secret("secret") .secret("secret")
.authorizationServicesEnabled(true) .authorizationServicesEnabled(true)
.redirectUris("http://localhost/resource-server-test") .redirectUris("http://localhost/resource-server-test")
.defaultRoles("uma_protection") .defaultRoles("uma_protection")
.directAccessGrants()) .directAccessGrants())
.client(ClientBuilder.create().clientId("test-client") .client(ClientBuilder.create().clientId(PAIRWISE_RESOURCE_SERVER_TEST)
.secret("secret") .secret("secret")
.authorizationServicesEnabled(true) .authorizationServicesEnabled(true)
.redirectUris("http://localhost/test-client") .redirectUris("http://localhost/resource-server-test")
.directAccessGrants()) .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()); .build());
} }
@Before @Before
public void configureAuthorization() throws Exception { 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(); AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation(); JSPolicyRepresentation policy = new JSPolicyRepresentation();
@ -106,6 +131,15 @@ public class EntitlementAPITest extends AbstractAuthzTest {
@Test @Test
public void testRptRequestWithoutResourceName() { 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 metadata = new Metadata();
metadata.setIncludeResourceName(false); metadata.setIncludeResourceName(false);
@ -116,32 +150,51 @@ public class EntitlementAPITest extends AbstractAuthzTest {
request.setMetadata(metadata); request.setMetadata(metadata);
request.addPermission("Resource 1"); request.addPermission("Resource 1");
return getAuthzClient().authorization("marta", "password").authorize(request); return getAuthzClient(configFile).authorization("marta", "password").authorize(request);
}); });
} }
@Test @Test
public void testRptRequestWithResourceName() { 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 metadata = new Metadata();
metadata.setIncludeResourceName(true); metadata.setIncludeResourceName(true);
assertResponse(metadata, () -> getAuthzClient().authorization("marta", "password").authorize()); assertResponse(metadata, () -> getAuthzClient(configFile).authorization("marta", "password").authorize());
AuthorizationRequest request = new AuthorizationRequest(); AuthorizationRequest request = new AuthorizationRequest();
request.setMetadata(metadata); request.setMetadata(metadata);
request.addPermission("Resource 13"); request.addPermission("Resource 13");
assertResponse(metadata, () -> getAuthzClient().authorization("marta", "password").authorize(request)); assertResponse(metadata, () -> getAuthzClient(configFile).authorization("marta", "password").authorize(request));
request.setMetadata(null); request.setMetadata(null);
assertResponse(metadata, () -> getAuthzClient().authorization("marta", "password").authorize(request)); assertResponse(metadata, () -> getAuthzClient(configFile).authorization("marta", "password").authorize(request));
} }
@Test @Test
public void testPermissionLimit() { 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(); AuthorizationRequest request = new AuthorizationRequest();
for (int i = 1; i <= 10; i++) { for (int i = 1; i <= 10; i++) {
@ -154,7 +207,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
request.setMetadata(metadata); 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()); AccessToken rpt = toAccessToken(response.getToken());
List<Permission> permissions = rpt.getAuthorization().getPermissions(); List<Permission> permissions = rpt.getAuthorization().getPermissions();
@ -174,7 +227,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
request.setMetadata(metadata); request.setMetadata(metadata);
request.setRpt(response.getToken()); request.setRpt(response.getToken());
response = getAuthzClient().authorization("marta", "password").authorize(request); response = getAuthzClient(configFile).authorization("marta", "password").authorize(request);
rpt = toAccessToken(response.getToken()); rpt = toAccessToken(response.getToken());
permissions = rpt.getAuthorization().getPermissions(); permissions = rpt.getAuthorization().getPermissions();
@ -198,7 +251,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
request.setMetadata(metadata); request.setMetadata(metadata);
request.setRpt(response.getToken()); request.setRpt(response.getToken());
response = getAuthzClient().authorization("marta", "password").authorize(request); response = getAuthzClient(configFile).authorization("marta", "password").authorize(request);
rpt = toAccessToken(response.getToken()); rpt = toAccessToken(response.getToken());
permissions = rpt.getAuthorization().getPermissions(); permissions = rpt.getAuthorization().getPermissions();
@ -221,7 +274,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
request.setMetadata(metadata); request.setMetadata(metadata);
request.setRpt(response.getToken()); request.setRpt(response.getToken());
response = getAuthzClient().authorization("marta", "password").authorize(request); response = getAuthzClient(configFile).authorization("marta", "password").authorize(request);
rpt = toAccessToken(response.getToken()); rpt = toAccessToken(response.getToken());
permissions = rpt.getAuthorization().getPermissions(); permissions = rpt.getAuthorization().getPermissions();
@ -236,15 +289,46 @@ public class EntitlementAPITest extends AbstractAuthzTest {
@Test @Test
public void testResourceServerAsAudience() throws Exception { 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(); AuthorizationRequest request = new AuthorizationRequest();
request.addPermission("Resource 1"); request.addPermission("Resource 1");
String accessToken = new OAuthClient().realm("authz-test").clientId("test-client").doGrantAccessTokenRequest("secret", "marta", "password").getAccessToken(); String accessToken = new OAuthClient().realm("authz-test").clientId(testClientId).doGrantAccessTokenRequest("secret", "marta", "password").getAccessToken();
AuthorizationResponse response = getAuthzClient().authorization(accessToken).authorize(request); AuthorizationResponse response = getAuthzClient(configFile).authorization(accessToken).authorize(request);
AccessToken rpt = toAccessToken(response.getToken()); AccessToken rpt = toAccessToken(response.getToken());
assertEquals("resource-server-test", rpt.getAudience()[0]); assertEquals(resourceServerClientId, rpt.getAudience()[0]);
} }
private void assertResponse(Metadata metadata, Supplier<AuthorizationResponse> responseSupplier) { private void assertResponse(Metadata metadata, Supplier<AuthorizationResponse> responseSupplier) {
@ -268,15 +352,15 @@ public class EntitlementAPITest extends AbstractAuthzTest {
return adminClient.realm("authz-test"); return adminClient.realm("authz-test");
} }
private ClientResource getClient(RealmResource realm) { private ClientResource getClient(RealmResource realm, String clientId) {
ClientsResource clients = realm.clients(); 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) { if (authzClient == null) {
try { 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) { } catch (IOException cause) {
throw new RuntimeException("Failed to create authz client", cause); throw new RuntimeException("Failed to create authz client", cause);
} }

View file

@ -198,4 +198,12 @@ public class ClientBuilder {
rep.getProtocolMappers().addAll(Arrays.asList(mappers)); rep.getProtocolMappers().addAll(Arrays.asList(mappers));
return this; 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));
}
} }

View file

@ -6,6 +6,7 @@ import org.keycloak.protocol.oidc.mappers.AddressMapper;
import org.keycloak.protocol.oidc.mappers.HardcodedClaim; import org.keycloak.protocol.oidc.mappers.HardcodedClaim;
import org.keycloak.protocol.oidc.mappers.HardcodedRole; import org.keycloak.protocol.oidc.mappers.HardcodedRole;
import org.keycloak.protocol.oidc.mappers.RoleNameMapper; 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.ScriptBasedOIDCProtocolMapper;
import org.keycloak.protocol.oidc.mappers.UserAttributeMapper; import org.keycloak.protocol.oidc.mappers.UserAttributeMapper;
import org.keycloak.protocol.oidc.mappers.UserClientRoleMappingMapper; 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);
}
} }

View file

@ -0,0 +1,8 @@
{
"realm": "authz-test",
"auth-server-url" : "http://localhost:8180/auth",
"resource" : "pairwise-resource-server-test",
"credentials": {
"secret": "secret"
}
}