コード例 #1
0
  @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()));
  }
コード例 #2
0
  /**
   * 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;
  }
コード例 #3
0
ファイル: UserAdapter.java プロジェクト: hh201020/keycloak
  @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;
  }
コード例 #4
0
ファイル: ClientResource.java プロジェクト: stianst/keycloak
  /**
   * 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;
  }
コード例 #5
0
  /**
   * 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();
  }
コード例 #6
0
ファイル: ClientAdapter.java プロジェクト: tfzhang/keycloak
  @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());
  }
コード例 #7
0
  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);
    }
  }
コード例 #8
0
ファイル: UserAdapter.java プロジェクト: niuhw/keycloak
  @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;
  }
コード例 #9
0
  @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);
                      }
                    });
          }
        });
  }
コード例 #10
0
 /**
  * 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;
 }
コード例 #11
0
ファイル: ClientAdapter.java プロジェクト: tfzhang/keycloak
  @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;
  }
コード例 #12
0
ファイル: AccountService.java プロジェクト: rishiHPE/keycloak
  @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();
  }
コード例 #13
0
ファイル: TokenManager.java プロジェクト: majinding/keycloak
  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;
  }
コード例 #14
0
ファイル: ClientManager.java プロジェクト: gautric/keycloak
  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;
    }
  }
コード例 #15
0
  /**
   * 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);
  }
コード例 #16
0
ファイル: SamlService.java プロジェクト: gautric/keycloak
    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);
      }
    }
コード例 #17
0
  // 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());
  }
コード例 #18
0
ファイル: ClientManager.java プロジェクト: gautric/keycloak
  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);
    }
  }
コード例 #19
0
ファイル: ClientAdapter.java プロジェクト: tfzhang/keycloak
 @Override
 public String getId() {
   if (updated != null) return updated.getId();
   return cached.getId();
 }