@Test public void testGetById() { Assert.assertEquals(realm1, model.getRealm("id1")); Assert.assertEquals(realm1, model.getRealmByName("realm1")); Assert.assertEquals(realm2, model.getRealm("id2")); Assert.assertEquals(realm2, model.getRealmByName("realm2")); ClientModel r1app1 = realm1.getClientByClientId("app1"); ClientModel r1app2 = realm1.getClientByClientId("app2"); ClientModel r2app1 = realm2.getClientByClientId("app1"); ClientModel r2app2 = realm2.getClientByClientId("app2"); Assert.assertEquals(r1app1, realm1.getClientById(r1app1.getId())); Assert.assertNull(realm2.getClientById(r1app1.getId())); ClientModel r2cl1 = realm2.getClientByClientId("cl1"); Assert.assertEquals(r2cl1.getId(), realm2.getClientById(r2cl1.getId()).getId()); Assert.assertNull(realm1.getClientByClientId(r2cl1.getId())); RoleModel r1App1Role = r1app1.getRole("app1Role1"); Assert.assertEquals(r1App1Role, realm1.getRoleById(r1App1Role.getId())); Assert.assertNull(realm2.getRoleById(r1App1Role.getId())); RoleModel r2Role1 = realm2.getRole("role2"); Assert.assertNull(realm1.getRoleById(r2Role1.getId())); Assert.assertEquals(r2Role1, realm2.getRoleById(r2Role1.getId())); }
/** * Get consents granted by the user * * @param id User id * @return */ @Path("{id}/consents") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) public List<Map<String, Object>> getConsents(final @PathParam("id") String id) { auth.requireView(); UserModel user = session.users().getUserById(id, realm); if (user == null) { throw new NotFoundException("User not found"); } List<Map<String, Object>> result = new LinkedList<>(); Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user); for (ClientModel client : realm.getClients()) { UserConsentModel consent = user.getConsentByClient(client.getId()); boolean hasOfflineToken = offlineClients.contains(client); if (consent == null && !hasOfflineToken) { continue; } UserConsentRepresentation rep = (consent == null) ? null : ModelToRepresentation.toRepresentation(consent); Map<String, Object> currentRep = new HashMap<>(); currentRep.put("clientId", client.getClientId()); currentRep.put( "grantedProtocolMappers", (rep == null ? Collections.emptyMap() : rep.getGrantedProtocolMappers())); currentRep.put( "grantedRealmRoles", (rep == null ? Collections.emptyList() : rep.getGrantedRealmRoles())); currentRep.put( "grantedClientRoles", (rep == null ? Collections.emptyMap() : rep.getGrantedClientRoles())); List<Map<String, String>> additionalGrants = new LinkedList<>(); if (hasOfflineToken) { Map<String, String> offlineTokens = new HashMap<>(); offlineTokens.put("client", client.getId()); // TODO: translate offlineTokens.put("key", "Offline Token"); additionalGrants.add(offlineTokens); } currentRep.put("additionalGrants", additionalGrants); result.add(currentRep); } return result; }
@Override public Set<RoleModel> getClientRoleMappings(ClientModel app) { Set<RoleModel> roleMappings = getRoleMappings(); Set<RoleModel> roles = new HashSet<RoleModel>(); for (RoleModel role : roleMappings) { RoleContainerModel container = role.getContainer(); if (container instanceof ClientModel) { ClientModel appModel = (ClientModel) container; if (appModel.getId().equals(app.getId())) { roles.add(role); } } } return roles; }
/** * Get offline sessions for client * * <p>Returns a list of offline user sessions associated with this client * * @param firstResult Paging offset * @param maxResults Maximum results size (defaults to 100) * @return */ @Path("offline-sessions") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) public List<UserSessionRepresentation> getOfflineUserSessions( @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) { auth.requireView(); if (client == null) { throw new NotFoundException("Could not find client"); } firstResult = firstResult != null ? firstResult : -1; maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS; List<UserSessionRepresentation> sessions = new ArrayList<UserSessionRepresentation>(); List<UserSessionModel> userSessions = session .sessions() .getOfflineUserSessions(client.getRealm(), client, firstResult, maxResults); for (UserSessionModel userSession : userSessions) { UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession); // Update lastSessionRefresh with the timestamp from clientSession for (ClientSessionModel clientSession : userSession.getClientSessions()) { if (client.getId().equals(clientSession.getClient().getId())) { rep.setLastAccess(Time.toMillis(clientSession.getTimestamp())); break; } } sessions.add(rep); } return sessions; }
/** * Revoke consent and offline tokens for particular client from user * * @param id User id * @param clientId Client id */ @Path("{id}/consents/{client}") @DELETE @NoCache public void revokeConsent( final @PathParam("id") String id, final @PathParam("client") String clientId) { auth.requireManage(); UserModel user = session.users().getUserById(id, realm); if (user == null) { throw new NotFoundException("User not found"); } ClientModel client = realm.getClientByClientId(clientId); boolean revokedConsent = user.revokeConsentForClient(client.getId()); boolean revokedOfflineToken = new UserSessionManager(session).revokeOfflineToken(user, client); if (revokedConsent) { // Logout clientSessions for this user and client AuthenticationManager.backchannelUserFromClient( session, realm, user, client, uriInfo, headers); } if (!revokedConsent && !revokedOfflineToken) { throw new NotFoundException("Consent nor offline token not found"); } adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success(); }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || !(o instanceof ClientModel)) return false; ClientModel that = (ClientModel) o; return that.getId().equals(getId()); }
public ApplicationsBean(KeycloakSession session, RealmModel realm, UserModel user) { Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user); List<ClientModel> realmClients = realm.getClients(); for (ClientModel client : realmClients) { // Don't show bearerOnly clients if (client.isBearerOnly()) { continue; } Set<RoleModel> availableRoles = TokenManager.getAccess(null, false, client, user); // Don't show applications, which user doesn't have access into (any available roles) if (availableRoles.isEmpty()) { continue; } List<RoleModel> realmRolesAvailable = new LinkedList<RoleModel>(); MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable = new MultivaluedHashMap<String, ClientRoleEntry>(); processRoles(availableRoles, realmRolesAvailable, resourceRolesAvailable); List<RoleModel> realmRolesGranted = new LinkedList<RoleModel>(); MultivaluedHashMap<String, ClientRoleEntry> resourceRolesGranted = new MultivaluedHashMap<String, ClientRoleEntry>(); List<String> claimsGranted = new LinkedList<String>(); if (client.isConsentRequired()) { UserConsentModel consent = user.getConsentByClient(client.getId()); if (consent != null) { processRoles(consent.getGrantedRoles(), realmRolesGranted, resourceRolesGranted); for (ProtocolMapperModel protocolMapper : consent.getGrantedProtocolMappers()) { claimsGranted.add(protocolMapper.getConsentText()); } } } List<String> additionalGrants = new ArrayList<>(); if (offlineClients.contains(client)) { additionalGrants.add("${offlineToken}"); } ApplicationEntry appEntry = new ApplicationEntry( realmRolesAvailable, resourceRolesAvailable, realmRolesGranted, resourceRolesGranted, client, claimsGranted, additionalGrants); applications.add(appEntry); } }
@Override public Set<RoleModel> getClientRoleMappings(ClientModel app) { Set<RoleModel> result = new HashSet<RoleModel>(); for (RoleModel role : allRoles) { RoleEntity roleEntity = ((RoleAdapter) role).getRoleEntity(); if (app.getId().equals(roleEntity.getClientId())) { result.add(new RoleAdapter(realm, roleEntity, app)); } } return result; }
@Override public void postInit(KeycloakSessionFactory factory) { factory.register( event -> { if (event instanceof ClientRemovedEvent) { KeycloakSession keycloakSession = ((ClientRemovedEvent) event).getKeycloakSession(); AuthorizationProvider provider = keycloakSession.getProvider(AuthorizationProvider.class); PolicyStore policyStore = provider.getStoreFactory().getPolicyStore(); ClientModel removedClient = ((ClientRemovedEvent) event).getClient(); policyStore .findByType(getId()) .forEach( policy -> { List<String> clients = new ArrayList<>(); for (String clientId : getClients(policy)) { if (!clientId.equals(removedClient.getId())) { clients.add(clientId); } } try { if (clients.isEmpty()) { policyStore .findDependentPolicies(policy.getId()) .forEach( dependentPolicy -> { dependentPolicy.removeAssociatedPolicy(policy); }); policyStore.delete(policy.getId()); } else { policy .getConfig() .put("clients", JsonSerialization.writeValueAsString(clients)); } } catch (IOException e) { throw new RuntimeException( "Error while synchronizing clients with policy [" + policy.getName() + "].", e); } }); } }); }
/** * Get client session stats * * <p>Returns a JSON map. The key is the client id, the value is the number of sessions that * currently are active with that client. Only clients that actually have a session associated * with them will be in this map. * * @return */ @Path("client-session-stats") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) public List<Map<String, String>> getClientSessionStats() { auth.requireView(); List<Map<String, String>> data = new LinkedList<Map<String, String>>(); for (ClientModel client : realm.getClients()) { int size = session.sessions().getActiveUserSessions(client.getRealm(), client); if (size == 0) continue; Map<String, String> map = new HashMap<String, String>(); map.put("id", client.getId()); map.put("clientId", client.getClientId()); map.put("active", size + ""); data.add(map); } return data; }
@Override public Set<RoleModel> getClientScopeMappings(ClientModel client) { Set<RoleModel> roleMappings = client.getScopeMappings(); Set<RoleModel> appRoles = new HashSet<RoleModel>(); for (RoleModel role : roleMappings) { RoleContainerModel container = role.getContainer(); if (container instanceof RealmModel) { } else { ClientModel app = (ClientModel) container; if (app.getId().equals(getId())) { appRoles.add(role); } } } return appRoles; }
@Path("revoke-grant") @POST public Response processRevokeGrant(final MultivaluedMap<String, String> formData) { if (auth == null) { return login("applications"); } require(AccountRoles.MANAGE_ACCOUNT); csrfCheck(formData); String clientId = formData.getFirst("clientId"); if (clientId == null) { return account.setError(Messages.CLIENT_NOT_FOUND).createResponse(AccountPages.APPLICATIONS); } ClientModel client = realm.getClientById(clientId); if (client == null) { return account.setError(Messages.CLIENT_NOT_FOUND).createResponse(AccountPages.APPLICATIONS); } // Revoke grant in UserModel UserModel user = auth.getUser(); user.revokeConsentForClient(client.getId()); OfflineTokenUtils.revokeOfflineToken(session, realm, user, client); // Logout clientSessions for this user and client AuthenticationManager.backchannelUserFromClient(session, realm, user, client, uriInfo, headers); event .event(EventType.REVOKE_GRANT) .client(auth.getClient()) .user(auth.getUser()) .detail(Details.REVOKED_CLIENT, client.getClientId()) .success(); setReferrerOnPage(); UriBuilder builder = Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "applicationsPage"); String referrer = uriInfo.getQueryParameters().getFirst("referrer"); if (referrer != null) { builder.queryParam("referrer", referrer); } URI location = builder.build(realm.getName()); return Response.seeOther(location).build(); }
public AccessTokenResponse refreshAccessToken( KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel authorizedClient, String encodedRefreshToken, EventBuilder event, HttpHeaders headers) throws OAuthErrorException { RefreshToken refreshToken = verifyRefreshToken(realm, encodedRefreshToken); event .user(refreshToken.getSubject()) .session(refreshToken.getSessionState()) .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()); TokenValidation validation = validateToken(session, uriInfo, connection, realm, refreshToken, headers); // validate authorizedClient is same as validated client if (!validation.clientSession.getClient().getId().equals(authorizedClient.getId())) { throw new OAuthErrorException( OAuthErrorException.INVALID_GRANT, "Invalid refresh token. Token client and authorized client don't match"); } int currentTime = Time.currentTime(); validation.userSession.setLastSessionRefresh(currentTime); AccessTokenResponse res = responseBuilder( realm, authorizedClient, event, session, validation.userSession, validation.clientSession) .accessToken(validation.newToken) .generateIDToken() .generateRefreshToken() .build(); return res; }
public boolean removeClient(RealmModel realm, ClientModel client) { if (realm.removeClient(client.getId())) { UserSessionProvider sessions = realmManager.getSession().sessions(); if (sessions != null) { sessions.onClientRemoved(realm, client); } UserSessionPersisterProvider sessionsPersister = realmManager.getSession().getProvider(UserSessionPersisterProvider.class); if (sessionsPersister != null) { sessionsPersister.onClientRemoved(realm, client); } UserModel serviceAccountUser = realmManager.getSession().users().getServiceAccount(client); if (serviceAccountUser != null) { new UserManager(realmManager.getSession()).removeUser(realm, serviceAccountUser); } return true; } else { return false; } }
/** * OAuth grant page. You should not invoked this directly! * * @param formData * @return */ @Path("consent") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processConsent(final MultivaluedMap<String, String> formData) { event.event(EventType.LOGIN).detail(Details.RESPONSE_TYPE, "code"); if (!checkSsl()) { return ErrorPage.error(session, Messages.HTTPS_REQUIRED); } String code = formData.getFirst("code"); ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm); if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT.name())) { event.error(Errors.INVALID_CODE); return ErrorPage.error(session, Messages.INVALID_ACCESS_CODE); } ClientSessionModel clientSession = accessCode.getClientSession(); event.detail(Details.CODE_ID, clientSession.getId()); String redirect = clientSession.getRedirectUri(); UserSessionModel userSession = clientSession.getUserSession(); UserModel user = userSession.getUser(); ClientModel client = clientSession.getClient(); event .client(client) .user(user) .detail(Details.RESPONSE_TYPE, "code") .detail(Details.REDIRECT_URI, redirect); event.detail(Details.AUTH_METHOD, userSession.getAuthMethod()); event.detail(Details.USERNAME, userSession.getLoginUsername()); if (userSession.isRememberMe()) { event.detail(Details.REMEMBER_ME, "true"); } if (!AuthenticationManager.isSessionValid(realm, userSession)) { AuthenticationManager.backchannelLogout( session, realm, userSession, uriInfo, clientConnection, headers, true); event.error(Errors.INVALID_CODE); return ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE); } event.session(userSession); if (formData.containsKey("cancel")) { LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod()); protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(uriInfo); event.error(Errors.REJECTED_BY_USER); return protocol.consentDenied(clientSession); } UserConsentModel grantedConsent = user.getConsentByClient(client.getId()); if (grantedConsent == null) { grantedConsent = new UserConsentModel(client); user.addConsent(grantedConsent); } for (RoleModel role : accessCode.getRequestedRoles()) { grantedConsent.addGrantedRole(role); } for (ProtocolMapperModel protocolMapper : accessCode.getRequestedProtocolMappers()) { if (protocolMapper.isConsentRequired() && protocolMapper.getConsentText() != null) { grantedConsent.addGrantedProtocolMapper(protocolMapper); } } user.updateConsent(grantedConsent); event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); event.success(); return authManager.redirectAfterSuccessfulFlow( session, realm, userSession, clientSession, request, uriInfo, clientConnection); }
protected Response logoutRequest( LogoutRequestType logoutRequest, ClientModel client, String relayState) { SamlClient samlClient = new SamlClient(client); // validate destination if (logoutRequest.getDestination() != null && !uriInfo.getAbsolutePath().equals(logoutRequest.getDestination())) { event.detail(Details.REASON, "invalid_destination"); event.error(Errors.INVALID_SAML_LOGOUT_REQUEST); return ErrorPage.error(session, Messages.INVALID_REQUEST); } // authenticate identity cookie, but ignore an access token timeout as we're logging out // anyways. AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, false); if (authResult != null) { String logoutBinding = getBindingType(); if ("true".equals(samlClient.forcePostBinding())) logoutBinding = SamlProtocol.SAML_POST_BINDING; String bindingUri = SamlProtocol.getLogoutServiceUrl(uriInfo, client, logoutBinding); UserSessionModel userSession = authResult.getSession(); userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING_URI, bindingUri); if (samlClient.requiresRealmSignature()) { userSession.setNote( SamlProtocol.SAML_LOGOUT_SIGNATURE_ALGORITHM, samlClient.getSignatureAlgorithm().toString()); } if (relayState != null) userSession.setNote(SamlProtocol.SAML_LOGOUT_RELAY_STATE, relayState); userSession.setNote(SamlProtocol.SAML_LOGOUT_REQUEST_ID, logoutRequest.getID()); userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING, logoutBinding); userSession.setNote( SamlProtocol.SAML_LOGOUT_CANONICALIZATION, samlClient.getCanonicalizationMethod()); userSession.setNote( AuthenticationManager.KEYCLOAK_LOGOUT_PROTOCOL, SamlProtocol.LOGIN_PROTOCOL); // remove client from logout requests for (ClientSessionModel clientSession : userSession.getClientSessions()) { if (clientSession.getClient().getId().equals(client.getId())) { clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT.name()); } } logger.debug("browser Logout"); return authManager.browserLogout( session, realm, userSession, uriInfo, clientConnection, headers); } else if (logoutRequest.getSessionIndex() != null) { for (String sessionIndex : logoutRequest.getSessionIndex()) { ClientSessionModel clientSession = session.sessions().getClientSession(realm, sessionIndex); if (clientSession == null) continue; UserSessionModel userSession = clientSession.getUserSession(); if (clientSession.getClient().getClientId().equals(client.getClientId())) { // remove requesting client from logout clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT.name()); // Remove also other clientSessions of this client as there could be more in this // UserSession if (userSession != null) { for (ClientSessionModel clientSession2 : userSession.getClientSessions()) { if (clientSession2.getClient().getId().equals(client.getId())) { clientSession2.setAction(ClientSessionModel.Action.LOGGED_OUT.name()); } } } } try { authManager.backchannelLogout( session, realm, userSession, uriInfo, clientConnection, headers, true); } catch (Exception e) { logger.warn("Failure with backchannel logout", e); } } } // default String logoutBinding = getBindingType(); String logoutBindingUri = SamlProtocol.getLogoutServiceUrl(uriInfo, client, logoutBinding); String logoutRelayState = relayState; SAML2LogoutResponseBuilder builder = new SAML2LogoutResponseBuilder(); builder.logoutRequestID(logoutRequest.getID()); builder.destination(logoutBindingUri); builder.issuer(RealmsResource.realmBaseUrl(uriInfo).build(realm.getName()).toString()); JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder().relayState(logoutRelayState); if (samlClient.requiresRealmSignature()) { SignatureAlgorithm algorithm = samlClient.getSignatureAlgorithm(); KeyManager.ActiveKey keys = session.keys().getActiveKey(realm); binding .signatureAlgorithm(algorithm) .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()) .signDocument(); } try { if (SamlProtocol.SAML_POST_BINDING.equals(logoutBinding)) { return binding.postBinding(builder.buildDocument()).response(logoutBindingUri); } else { return binding.redirectBinding(builder.buildDocument()).response(logoutBindingUri); } } catch (Exception e) { throw new RuntimeException(e); } }
// Moved to static method, so it's possible to test this from other places too (for example // export-import tests) public static void assertDataImportedInRealm(KeycloakSession session, RealmModel realm) { Assert.assertTrue(realm.isVerifyEmail()); List<RequiredCredentialModel> creds = realm.getRequiredCredentials(); Assert.assertEquals(1, creds.size()); RequiredCredentialModel cred = creds.get(0); Assert.assertEquals("password", cred.getFormLabel()); Assert.assertEquals(3, realm.getDefaultRoles().size()); Assert.assertNotNull(realm.getRole("foo")); Assert.assertNotNull(realm.getRole("bar")); UserModel user = session.users().getUserByUsername("loginclient", realm); Assert.assertNotNull(user); Assert.assertEquals(0, session.users().getFederatedIdentities(user, realm).size()); List<ClientModel> resources = realm.getClients(); Assert.assertEquals(7, resources.size()); // Test applications imported ClientModel application = realm.getClientByClientId("Application"); ClientModel otherApp = realm.getClientByClientId("OtherApp"); ClientModel accountApp = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); ClientModel nonExisting = realm.getClientByClientId("NonExisting"); Assert.assertNotNull(application); Assert.assertNotNull(otherApp); Assert.assertNull(nonExisting); Map<String, ClientModel> clients = realm.getClientNameMap(); Assert.assertEquals(7, clients.size()); Assert.assertTrue(clients.values().contains(application)); Assert.assertTrue(clients.values().contains(otherApp)); Assert.assertTrue(clients.values().contains(accountApp)); realm.getClients().containsAll(clients.values()); Assert.assertEquals("Applicationn", application.getName()); Assert.assertEquals(50, application.getNodeReRegistrationTimeout()); Map<String, Integer> appRegisteredNodes = application.getRegisteredNodes(); Assert.assertEquals(2, appRegisteredNodes.size()); Assert.assertTrue(10 == appRegisteredNodes.get("node1")); Assert.assertTrue(20 == appRegisteredNodes.get("172.10.15.20")); // test clientAuthenticatorType Assert.assertEquals(application.getClientAuthenticatorType(), "client-secret"); Assert.assertEquals(otherApp.getClientAuthenticatorType(), "client-jwt"); // Test finding applications by ID Assert.assertNull(realm.getClientById("982734")); Assert.assertEquals(application, realm.getClientById(application.getId())); // Test role mappings UserModel admin = session.users().getUserByUsername("admin", realm); // user without creation timestamp in import Assert.assertNull(admin.getCreatedTimestamp()); Set<RoleModel> allRoles = admin.getRoleMappings(); Assert.assertEquals(3, allRoles.size()); Assert.assertTrue(allRoles.contains(realm.getRole("admin"))); Assert.assertTrue(allRoles.contains(application.getRole("app-admin"))); Assert.assertTrue(allRoles.contains(otherApp.getRole("otherapp-admin"))); Assert.assertTrue(application.getRole("app-admin").isScopeParamRequired()); Assert.assertFalse(otherApp.getRole("otherapp-admin").isScopeParamRequired()); Assert.assertFalse(otherApp.getRole("otherapp-user").isScopeParamRequired()); UserModel wburke = session.users().getUserByUsername("wburke", realm); // user with creation timestamp in import Assert.assertEquals(new Long(123654), wburke.getCreatedTimestamp()); allRoles = wburke.getRoleMappings(); Assert.assertEquals(2, allRoles.size()); Assert.assertFalse(allRoles.contains(realm.getRole("admin"))); Assert.assertTrue(allRoles.contains(application.getRole("app-user"))); Assert.assertTrue(allRoles.contains(otherApp.getRole("otherapp-user"))); Assert.assertEquals(0, wburke.getRealmRoleMappings().size()); UserModel loginclient = session.users().getUserByUsername("loginclient", realm); // user with creation timestamp as string in import Assert.assertEquals(new Long(123655), loginclient.getCreatedTimestamp()); Set<RoleModel> realmRoles = admin.getRealmRoleMappings(); Assert.assertEquals(1, realmRoles.size()); Assert.assertEquals("admin", realmRoles.iterator().next().getName()); Set<RoleModel> appRoles = admin.getClientRoleMappings(application); Assert.assertEquals(1, appRoles.size()); Assert.assertEquals("app-admin", appRoles.iterator().next().getName()); // Test attributes Map<String, List<String>> attrs = wburke.getAttributes(); Assert.assertEquals(1, attrs.size()); List<String> attrVals = attrs.get("email"); Assert.assertEquals(1, attrVals.size()); Assert.assertEquals("*****@*****.**", attrVals.get(0)); attrs = admin.getAttributes(); Assert.assertEquals(2, attrs.size()); attrVals = attrs.get("key1"); Assert.assertEquals(1, attrVals.size()); Assert.assertEquals("val1", attrVals.get(0)); attrVals = attrs.get("key2"); Assert.assertEquals(2, attrVals.size()); Assert.assertTrue(attrVals.contains("val21") && attrVals.contains("val22")); // Test client ClientModel oauthClient = realm.getClientByClientId("oauthclient"); Assert.assertEquals("clientpassword", oauthClient.getSecret()); Assert.assertEquals(true, oauthClient.isEnabled()); Assert.assertNotNull(oauthClient); // Test scope relationship Set<RoleModel> allScopes = oauthClient.getScopeMappings(); Assert.assertEquals(2, allScopes.size()); Assert.assertTrue(allScopes.contains(realm.getRole("admin"))); Assert.assertTrue(allScopes.contains(application.getRole("app-user"))); Set<RoleModel> realmScopes = oauthClient.getRealmScopeMappings(); Assert.assertTrue(realmScopes.contains(realm.getRole("admin"))); Set<RoleModel> appScopes = application.getClientScopeMappings(oauthClient); Assert.assertTrue(appScopes.contains(application.getRole("app-user"))); // Test social linking UserModel socialUser = session.users().getUserByUsername("mySocialUser", realm); Set<FederatedIdentityModel> socialLinks = session.users().getFederatedIdentities(socialUser, realm); Assert.assertEquals(3, socialLinks.size()); boolean facebookFound = false; boolean googleFound = false; boolean twitterFound = false; for (FederatedIdentityModel federatedIdentityModel : socialLinks) { if ("facebook".equals(federatedIdentityModel.getIdentityProvider())) { facebookFound = true; Assert.assertEquals(federatedIdentityModel.getUserId(), "facebook1"); Assert.assertEquals(federatedIdentityModel.getUserName(), "fbuser1"); } else if ("google".equals(federatedIdentityModel.getIdentityProvider())) { googleFound = true; Assert.assertEquals(federatedIdentityModel.getUserId(), "google1"); Assert.assertEquals(federatedIdentityModel.getUserName(), "*****@*****.**"); } else if ("twitter".equals(federatedIdentityModel.getIdentityProvider())) { twitterFound = true; Assert.assertEquals(federatedIdentityModel.getUserId(), "twitter1"); Assert.assertEquals(federatedIdentityModel.getUserName(), "twuser1"); } } Assert.assertTrue(facebookFound && twitterFound && googleFound); UserModel foundSocialUser = session .users() .getUserByFederatedIdentity( new FederatedIdentityModel("facebook", "facebook1", "fbuser1"), realm); Assert.assertEquals(foundSocialUser.getUsername(), socialUser.getUsername()); Assert.assertNull( session .users() .getUserByFederatedIdentity( new FederatedIdentityModel("facebook", "not-existing", "not-existing"), realm)); FederatedIdentityModel foundSocialLink = session.users().getFederatedIdentity(socialUser, "facebook", realm); Assert.assertEquals("facebook1", foundSocialLink.getUserId()); Assert.assertEquals("fbuser1", foundSocialLink.getUserName()); Assert.assertEquals("facebook", foundSocialLink.getIdentityProvider()); // Test removing social link Assert.assertTrue(session.users().removeFederatedIdentity(realm, socialUser, "facebook")); Assert.assertNull(session.users().getFederatedIdentity(socialUser, "facebook", realm)); Assert.assertFalse(session.users().removeFederatedIdentity(realm, socialUser, "facebook")); session .users() .addFederatedIdentity( realm, socialUser, new FederatedIdentityModel("facebook", "facebook1", "fbuser1")); // Test smtp config Map<String, String> smtpConfig = realm.getSmtpConfig(); Assert.assertTrue(smtpConfig.size() == 3); Assert.assertEquals("*****@*****.**", smtpConfig.get("from")); Assert.assertEquals("localhost", smtpConfig.get("host")); Assert.assertEquals("3025", smtpConfig.get("port")); // Test identity providers List<IdentityProviderModel> identityProviders = realm.getIdentityProviders(); Assert.assertEquals(1, identityProviders.size()); IdentityProviderModel google = identityProviders.get(0); Assert.assertEquals("google1", google.getAlias()); Assert.assertEquals("google", google.getProviderId()); Assert.assertTrue(google.isEnabled()); Assert.assertEquals("googleId", google.getConfig().get("clientId")); Assert.assertEquals("googleSecret", google.getConfig().get("clientSecret")); // Test federation providers List<UserFederationProviderModel> fedProviders = realm.getUserFederationProviders(); Assert.assertTrue(fedProviders.size() == 2); UserFederationProviderModel ldap1 = fedProviders.get(0); Assert.assertEquals("MyLDAPProvider1", ldap1.getDisplayName()); Assert.assertEquals("ldap", ldap1.getProviderName()); Assert.assertEquals(1, ldap1.getPriority()); Assert.assertEquals("ldap://foo", ldap1.getConfig().get(LDAPConstants.CONNECTION_URL)); UserFederationProviderModel ldap2 = fedProviders.get(1); Assert.assertEquals("MyLDAPProvider2", ldap2.getDisplayName()); Assert.assertEquals("ldap://bar", ldap2.getConfig().get(LDAPConstants.CONNECTION_URL)); // Test federation mappers Set<UserFederationMapperModel> fedMappers1 = realm.getUserFederationMappersByFederationProvider(ldap1.getId()); Assert.assertTrue(fedMappers1.size() == 1); UserFederationMapperModel fullNameMapper = fedMappers1.iterator().next(); Assert.assertEquals("FullNameMapper", fullNameMapper.getName()); Assert.assertEquals( FullNameLDAPFederationMapperFactory.PROVIDER_ID, fullNameMapper.getFederationMapperType()); Assert.assertEquals(ldap1.getId(), fullNameMapper.getFederationProviderId()); Assert.assertEquals( "cn", fullNameMapper.getConfig().get(FullNameLDAPFederationMapper.LDAP_FULL_NAME_ATTRIBUTE)); // All builtin LDAP mappers should be here Set<UserFederationMapperModel> fedMappers2 = realm.getUserFederationMappersByFederationProvider(ldap2.getId()); Assert.assertTrue(fedMappers2.size() > 3); Set<UserFederationMapperModel> allMappers = realm.getUserFederationMappers(); Assert.assertEquals(allMappers.size(), fedMappers1.size() + fedMappers2.size()); // Assert that federation link wasn't created during import UserFederationProviderFactory factory = (UserFederationProviderFactory) session .getKeycloakSessionFactory() .getProviderFactory(UserFederationProvider.class, "dummy"); Assert.assertNull(factory.getInstance(session, null).getUserByUsername(realm, "wburke")); // Test builtin authentication flows AuthenticationFlowModel clientFlow = realm.getClientAuthenticationFlow(); Assert.assertEquals( DefaultAuthenticationFlows.CLIENT_AUTHENTICATION_FLOW, clientFlow.getAlias()); Assert.assertNotNull(realm.getAuthenticationFlowById(clientFlow.getId())); Assert.assertTrue(realm.getAuthenticationExecutions(clientFlow.getId()).size() > 0); AuthenticationFlowModel resetFlow = realm.getResetCredentialsFlow(); Assert.assertEquals(DefaultAuthenticationFlows.RESET_CREDENTIALS_FLOW, resetFlow.getAlias()); Assert.assertNotNull(realm.getAuthenticationFlowById(resetFlow.getId())); Assert.assertTrue(realm.getAuthenticationExecutions(resetFlow.getId()).size() > 0); // Test protocol mappers. Default application has all the builtin protocol mappers. OtherApp // just gss credential Assert.assertNotNull( application.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "username")); Assert.assertNotNull( application.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "email")); Assert.assertNotNull( application.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "given name")); Assert.assertNull( application.getProtocolMapperByName( OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME)); Assert.assertEquals(1, otherApp.getProtocolMappers().size()); Assert.assertNull( otherApp.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "username")); ProtocolMapperModel gssCredentialMapper = otherApp.getProtocolMapperByName( OIDCLoginProtocol.LOGIN_PROTOCOL, KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME); Assert.assertEquals( KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME, gssCredentialMapper.getName()); Assert.assertEquals(OIDCLoginProtocol.LOGIN_PROTOCOL, gssCredentialMapper.getProtocol()); Assert.assertEquals(UserSessionNoteMapper.PROVIDER_ID, gssCredentialMapper.getProtocolMapper()); String includeInAccessToken = gssCredentialMapper.getConfig().get(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN); String includeInIdToken = gssCredentialMapper.getConfig().get(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN); Assert.assertTrue(includeInAccessToken.equalsIgnoreCase("true")); Assert.assertTrue(includeInIdToken == null || Boolean.parseBoolean(includeInIdToken) == false); // Test user consents admin = session.users().getUserByUsername("admin", realm); Assert.assertEquals(2, admin.getConsents().size()); UserConsentModel appAdminConsent = admin.getConsentByClient(application.getId()); Assert.assertEquals(2, appAdminConsent.getGrantedRoles().size()); Assert.assertTrue( appAdminConsent.getGrantedProtocolMappers() == null || appAdminConsent.getGrantedProtocolMappers().isEmpty()); Assert.assertTrue(appAdminConsent.isRoleGranted(realm.getRole("admin"))); Assert.assertTrue(appAdminConsent.isRoleGranted(application.getRole("app-admin"))); UserConsentModel otherAppAdminConsent = admin.getConsentByClient(otherApp.getId()); Assert.assertEquals(1, otherAppAdminConsent.getGrantedRoles().size()); Assert.assertEquals(1, otherAppAdminConsent.getGrantedProtocolMappers().size()); Assert.assertTrue(otherAppAdminConsent.isRoleGranted(realm.getRole("admin"))); Assert.assertFalse(otherAppAdminConsent.isRoleGranted(application.getRole("app-admin"))); Assert.assertTrue(otherAppAdminConsent.isProtocolMapperGranted(gssCredentialMapper)); // Test service accounts Assert.assertFalse(application.isServiceAccountsEnabled()); Assert.assertTrue(otherApp.isServiceAccountsEnabled()); Assert.assertNull(session.users().getUserByServiceAccountClient(application)); UserModel linked = session.users().getUserByServiceAccountClient(otherApp); Assert.assertNotNull(linked); Assert.assertEquals("my-service-user", linked.getUsername()); }
public void enableServiceAccount(ClientModel client) { client.setServiceAccountsEnabled(true); // Add dedicated user for this service account if (realmManager.getSession().users().getServiceAccount(client) == null) { String username = ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + client.getClientId(); logger.debugf("Creating service account user '%s'", username); // Don't use federation for service account user UserModel user = realmManager.getSession().userStorage().addUser(client.getRealm(), username); user.setEnabled(true); user.setEmail(username + "@placeholder.org"); user.setServiceAccountClientLink(client.getId()); } // Add protocol mappers to retrieve clientId in access token if (client.getProtocolMapperByName( OIDCLoginProtocol.LOGIN_PROTOCOL, ServiceAccountConstants.CLIENT_ID_PROTOCOL_MAPPER) == null) { logger.debugf( "Creating service account protocol mapper '%s' for client '%s'", ServiceAccountConstants.CLIENT_ID_PROTOCOL_MAPPER, client.getClientId()); ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper( ServiceAccountConstants.CLIENT_ID_PROTOCOL_MAPPER, ServiceAccountConstants.CLIENT_ID, ServiceAccountConstants.CLIENT_ID, "String", false, "", true, true); client.addProtocolMapper(protocolMapper); } // Add protocol mappers to retrieve hostname and IP address of client in access token if (client.getProtocolMapperByName( OIDCLoginProtocol.LOGIN_PROTOCOL, ServiceAccountConstants.CLIENT_HOST_PROTOCOL_MAPPER) == null) { logger.debugf( "Creating service account protocol mapper '%s' for client '%s'", ServiceAccountConstants.CLIENT_HOST_PROTOCOL_MAPPER, client.getClientId()); ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper( ServiceAccountConstants.CLIENT_HOST_PROTOCOL_MAPPER, ServiceAccountConstants.CLIENT_HOST, ServiceAccountConstants.CLIENT_HOST, "String", false, "", true, true); client.addProtocolMapper(protocolMapper); } if (client.getProtocolMapperByName( OIDCLoginProtocol.LOGIN_PROTOCOL, ServiceAccountConstants.CLIENT_ADDRESS_PROTOCOL_MAPPER) == null) { logger.debugf( "Creating service account protocol mapper '%s' for client '%s'", ServiceAccountConstants.CLIENT_ADDRESS_PROTOCOL_MAPPER, client.getClientId()); ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper( ServiceAccountConstants.CLIENT_ADDRESS_PROTOCOL_MAPPER, ServiceAccountConstants.CLIENT_ADDRESS, ServiceAccountConstants.CLIENT_ADDRESS, "String", false, "", true, true); client.addProtocolMapper(protocolMapper); } }
@Override public String getId() { if (updated != null) return updated.getId(); return cached.getId(); }