예제 #1
0
  public static void attachClientSession(
      UserSessionModel session, ClientSessionModel clientSession) {
    if (clientSession.getUserSession() != null) {
      return;
    }

    UserModel user = session.getUser();
    clientSession.setUserSession(session);
    Set<String> requestedRoles = new HashSet<String>();
    // todo scope param protocol independent
    for (RoleModel r : TokenManager.getAccess(null, clientSession.getClient(), user)) {
      requestedRoles.add(r.getId());
    }
    clientSession.setRoles(requestedRoles);

    Set<String> requestedProtocolMappers = new HashSet<String>();
    for (ProtocolMapperModel protocolMapper : clientSession.getClient().getProtocolMappers()) {
      if (protocolMapper.getProtocol().equals(clientSession.getAuthMethod())) {
        requestedProtocolMappers.add(protocolMapper.getId());
      }
    }
    clientSession.setProtocolMappers(requestedProtocolMappers);

    Map<String, String> transferredNotes = clientSession.getUserSessionNotes();
    for (Map.Entry<String, String> entry : transferredNotes.entrySet()) {
      session.setNote(entry.getKey(), entry.getValue());
    }
  }
예제 #2
0
 @Override
 public ProtocolMapperModel getProtocolMapperById(String id) {
   for (ProtocolMapperModel mapping : cached.getProtocolMappers()) {
     if (mapping.getId().equals(id)) return mapping;
   }
   return null;
 }
예제 #3
0
 @Override
 public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
   for (ProtocolMapperModel mapping : cached.getProtocolMappers()) {
     if (mapping.getProtocol().equals(protocol) && mapping.getName().equals(name)) return mapping;
   }
   return null;
 }
예제 #4
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);
    }
  }
예제 #5
0
 public static ProtocolMapperModel create(String name, String role) {
   String mapperId = PROVIDER_ID;
   ProtocolMapperModel mapper = new ProtocolMapperModel();
   mapper.setName(name);
   mapper.setProtocolMapper(mapperId);
   mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
   Map<String, String> config = new HashMap<String, String>();
   config.put(ROLE_CONFIG, role);
   mapper.setConfig(config);
   return mapper;
 }
예제 #6
0
  // Update roles and protocolMappers to given consentEntity from the consentModel
  private void updateGrantedConsentEntity(
      UserConsentEntity consentEntity, UserConsentModel consentModel) {
    Collection<UserConsentProtocolMapperEntity> grantedProtocolMapperEntities =
        consentEntity.getGrantedProtocolMappers();
    Collection<UserConsentProtocolMapperEntity> mappersToRemove =
        new HashSet<UserConsentProtocolMapperEntity>(grantedProtocolMapperEntities);

    for (ProtocolMapperModel protocolMapper : consentModel.getGrantedProtocolMappers()) {
      UserConsentProtocolMapperEntity grantedProtocolMapperEntity =
          new UserConsentProtocolMapperEntity();
      grantedProtocolMapperEntity.setUserConsent(consentEntity);
      grantedProtocolMapperEntity.setProtocolMapperId(protocolMapper.getId());

      // Check if it's already there
      if (!grantedProtocolMapperEntities.contains(grantedProtocolMapperEntity)) {
        em.persist(grantedProtocolMapperEntity);
        em.flush();
        grantedProtocolMapperEntities.add(grantedProtocolMapperEntity);
      } else {
        mappersToRemove.remove(grantedProtocolMapperEntity);
      }
    }
    // Those mappers were no longer on consentModel and will be removed
    for (UserConsentProtocolMapperEntity toRemove : mappersToRemove) {
      grantedProtocolMapperEntities.remove(toRemove);
      em.remove(toRemove);
    }

    Collection<UserConsentRoleEntity> grantedRoleEntities = consentEntity.getGrantedRoles();
    Set<UserConsentRoleEntity> rolesToRemove =
        new HashSet<UserConsentRoleEntity>(grantedRoleEntities);
    for (RoleModel role : consentModel.getGrantedRoles()) {
      UserConsentRoleEntity consentRoleEntity = new UserConsentRoleEntity();
      consentRoleEntity.setUserConsent(consentEntity);
      consentRoleEntity.setRoleId(role.getId());

      // Check if it's already there
      if (!grantedRoleEntities.contains(consentRoleEntity)) {
        em.persist(consentRoleEntity);
        em.flush();
        grantedRoleEntities.add(consentRoleEntity);
      } else {
        rolesToRemove.remove(consentRoleEntity);
      }
    }
    // Those roles were no longer on consentModel and will be removed
    for (UserConsentRoleEntity toRemove : rolesToRemove) {
      grantedRoleEntities.remove(toRemove);
      em.remove(toRemove);
    }

    em.flush();
  }
  private static Map<String, ProtocolMapperRepresentation> getAllDefaultMappers(
      KeycloakSession session) {
    Map<String, ProtocolMapperRepresentation> allMappers =
        new HashMap<String, ProtocolMapperRepresentation>();

    List<ProviderFactory> loginProtocolFactories =
        session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class);

    for (ProviderFactory factory : loginProtocolFactories) {
      LoginProtocolFactory loginProtocolFactory = (LoginProtocolFactory) factory;
      List<ProtocolMapperModel> currentMappers = loginProtocolFactory.getDefaultBuiltinMappers();

      for (ProtocolMapperModel protocolMapper : currentMappers) {
        ProtocolMapperRepresentation rep = ModelToRepresentation.toRepresentation(protocolMapper);
        allMappers.put(protocolMapper.getName(), rep);
      }
    }

    return allMappers;
  }
 @Override
 public void transformAttributeStatement(
     AttributeStatementType attributeStatement,
     ProtocolMapperModel mappingModel,
     KeycloakSession session,
     UserSessionModel userSession,
     ClientSessionModel clientSession) {
   UserModel user = userSession.getUser();
   String attributeName = mappingModel.getConfig().get(ProtocolMapperUtils.USER_ATTRIBUTE);
   String attributeValue = user.getFirstAttribute(attributeName);
   if (attributeValue == null) return;
   AttributeStatementHelper.addAttribute(attributeStatement, mappingModel, attributeValue);
 }
예제 #9
0
  public void transformIDToken(
      KeycloakSession session,
      IDToken token,
      RealmModel realm,
      ClientModel client,
      UserModel user,
      UserSessionModel userSession,
      ClientSessionModel clientSession) {
    Set<ProtocolMapperModel> mappings =
        new ClientSessionCode(realm, clientSession).getRequestedProtocolMappers();
    KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
    for (ProtocolMapperModel mapping : mappings) {

      ProtocolMapper mapper =
          (ProtocolMapper)
              sessionFactory.getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper());
      if (mapper == null || !(mapper instanceof OIDCIDTokenMapper)) continue;
      token =
          ((OIDCIDTokenMapper) mapper)
              .transformIDToken(token, mapping, session, userSession, clientSession);
    }
  }
예제 #10
0
 @Override
 public AccessToken transformAccessToken(
     AccessToken token,
     ProtocolMapperModel mappingModel,
     KeycloakSession session,
     UserSessionModel userSession,
     ClientSessionModel clientSession) {
   String role = mappingModel.getConfig().get(ROLE_CONFIG);
   String[] scopedRole = KeycloakModelUtils.parseRole(role);
   String appName = scopedRole[0];
   String roleName = scopedRole[1];
   if (appName != null) {
     token.addAccess(appName).addRole(roleName);
   } else {
     AccessToken.Access access = token.getRealmAccess();
     if (access == null) {
       access = new AccessToken.Access();
       token.setRealmAccess(access);
     }
     access.addRole(role);
   }
   return token;
 }
예제 #11
0
  @Override
  public Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode) {
    ClientSessionModel clientSession = accessCode.getClientSession();
    ClientModel client = clientSession.getClient();
    SamlClient samlClient = new SamlClient(client);
    String requestID = clientSession.getNote(SAML_REQUEST_ID);
    String relayState = clientSession.getNote(GeneralConstants.RELAY_STATE);
    String redirectUri = clientSession.getRedirectUri();
    String responseIssuer = getResponseIssuer(realm);
    String nameIdFormat = getNameIdFormat(samlClient, clientSession);
    String nameId = getNameId(nameIdFormat, clientSession, userSession);

    // save NAME_ID and format in clientSession as they may be persistent or transient or email and
    // not username
    // we'll need to send this back on a logout
    clientSession.setNote(SAML_NAME_ID, nameId);
    clientSession.setNote(SAML_NAME_ID_FORMAT, nameIdFormat);

    SAML2LoginResponseBuilder builder = new SAML2LoginResponseBuilder();
    builder
        .requestID(requestID)
        .destination(redirectUri)
        .issuer(responseIssuer)
        .assertionExpiration(realm.getAccessCodeLifespan())
        .subjectExpiration(realm.getAccessTokenLifespan())
        .sessionIndex(clientSession.getId())
        .requestIssuer(clientSession.getClient().getClientId())
        .nameIdentifier(nameIdFormat, nameId)
        .authMethod(JBossSAMLURIConstants.AC_UNSPECIFIED.get());
    if (!samlClient.includeAuthnStatement()) {
      builder.disableAuthnStatement(true);
    }

    List<ProtocolMapperProcessor<SAMLAttributeStatementMapper>> attributeStatementMappers =
        new LinkedList<>();
    List<ProtocolMapperProcessor<SAMLLoginResponseMapper>> loginResponseMappers =
        new LinkedList<>();
    ProtocolMapperProcessor<SAMLRoleListMapper> roleListMapper = null;

    Set<ProtocolMapperModel> mappings = accessCode.getRequestedProtocolMappers();
    for (ProtocolMapperModel mapping : mappings) {

      ProtocolMapper mapper =
          (ProtocolMapper)
              session
                  .getKeycloakSessionFactory()
                  .getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper());
      if (mapper == null) continue;
      if (mapper instanceof SAMLAttributeStatementMapper) {
        attributeStatementMappers.add(
            new ProtocolMapperProcessor<SAMLAttributeStatementMapper>(
                (SAMLAttributeStatementMapper) mapper, mapping));
      }
      if (mapper instanceof SAMLLoginResponseMapper) {
        loginResponseMappers.add(
            new ProtocolMapperProcessor<SAMLLoginResponseMapper>(
                (SAMLLoginResponseMapper) mapper, mapping));
      }
      if (mapper instanceof SAMLRoleListMapper) {
        roleListMapper =
            new ProtocolMapperProcessor<SAMLRoleListMapper>((SAMLRoleListMapper) mapper, mapping);
      }
    }

    Document samlDocument = null;
    try {
      ResponseType samlModel = builder.buildModel();
      final AttributeStatementType attributeStatement =
          populateAttributeStatements(
              attributeStatementMappers, session, userSession, clientSession);
      populateRoles(roleListMapper, session, userSession, clientSession, attributeStatement);

      // SAML Spec 2.7.3 AttributeStatement must contain one or more Attribute or EncryptedAttribute
      if (attributeStatement.getAttributes().size() > 0) {
        AssertionType assertion = samlModel.getAssertions().get(0).getAssertion();
        assertion.addStatement(attributeStatement);
      }

      samlModel =
          transformLoginResponse(
              loginResponseMappers, samlModel, session, userSession, clientSession);
      samlDocument = builder.buildDocument(samlModel);
    } catch (Exception e) {
      logger.error("failed", e);
      return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
    }

    JaxrsSAML2BindingBuilder bindingBuilder = new JaxrsSAML2BindingBuilder();
    bindingBuilder.relayState(relayState);

    KeyManager keyManager = session.keys();
    KeyManager.ActiveKey keys = keyManager.getActiveKey(realm);

    if (samlClient.requiresRealmSignature()) {
      String canonicalization = samlClient.getCanonicalizationMethod();
      if (canonicalization != null) {
        bindingBuilder.canonicalizationMethod(canonicalization);
      }
      bindingBuilder
          .signatureAlgorithm(samlClient.getSignatureAlgorithm())
          .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
          .signDocument();
    }
    if (samlClient.requiresAssertionSignature()) {
      String canonicalization = samlClient.getCanonicalizationMethod();
      if (canonicalization != null) {
        bindingBuilder.canonicalizationMethod(canonicalization);
      }
      bindingBuilder
          .signatureAlgorithm(samlClient.getSignatureAlgorithm())
          .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
          .signAssertions();
    }
    if (samlClient.requiresEncryption()) {
      PublicKey publicKey = null;
      try {
        publicKey = SamlProtocolUtils.getEncryptionValidationKey(client);
      } catch (Exception e) {
        logger.error("failed", e);
        return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
      }
      bindingBuilder.encrypt(publicKey);
    }
    try {
      return buildAuthenticatedResponse(clientSession, redirectUri, samlDocument, bindingBuilder);
    } catch (Exception e) {
      logger.error("failed", e);
      return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
    }
  }
예제 #12
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());
  }
예제 #13
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);
  }