protected String createOidcClient(String name) {
   ClientRepresentation clientRep = new ClientRepresentation();
   clientRep.setClientId(name);
   clientRep.setName(name);
   clientRep.setRootUrl("foo");
   clientRep.setProtocol("openid-connect");
   return createClient(clientRep);
 }
 protected String createSamlClient(String name) {
   ClientRepresentation clientRep = new ClientRepresentation();
   clientRep.setClientId(name);
   clientRep.setName(name);
   clientRep.setProtocol("saml");
   clientRep.setAdminUrl("samlEndpoint");
   return createClient(clientRep);
 }
Exemple #3
0
 public static ClientResource findClientByClientId(RealmResource realm, String clientId) {
   for (ClientRepresentation c : realm.clients().findAll()) {
     if (c.getClientId().equals(clientId)) {
       return realm.clients().get(c.getId());
     }
   }
   return null;
 }
Exemple #4
0
  /**
   * Update the client
   *
   * @param rep
   * @return
   */
  @PUT
  @Consumes(MediaType.APPLICATION_JSON)
  public Response update(final ClientRepresentation rep) {
    auth.requireManage();

    if (client == null) {
      throw new NotFoundException("Could not find client");
    }

    ValidationMessages validationMessages = new ValidationMessages();
    if (!ClientValidator.validate(rep, validationMessages)
        || !PairwiseClientValidator.validate(session, rep, validationMessages)) {
      Properties messages =
          AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale());
      throw new ErrorResponseException(
          validationMessages.getStringMessages(),
          validationMessages.getStringMessages(messages),
          Response.Status.BAD_REQUEST);
    }

    try {
      updateClientFromRep(rep, client, session);
      adminEvent
          .operation(OperationType.UPDATE)
          .resourcePath(uriInfo)
          .representation(rep)
          .success();
      return Response.noContent().build();
    } catch (ModelDuplicateException e) {
      return ErrorResponse.exists("Client " + rep.getClientId() + " already exists");
    }
  }
Exemple #5
0
  /**
   * Get representation of the client
   *
   * @return
   */
  @GET
  @NoCache
  @Produces(MediaType.APPLICATION_JSON)
  public ClientRepresentation getClient() {
    auth.requireView();

    if (client == null) {
      throw new NotFoundException("Could not find client");
    }

    ClientRepresentation representation = ModelToRepresentation.toRepresentation(client);

    if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
      representation.setAuthorizationServicesEnabled(authorization().isEnabled());
    }

    return representation;
  }
Exemple #6
0
  /**
   * Generate a new registration access token for the client
   *
   * @return
   */
  @Path("registration-access-token")
  @POST
  @Produces(MediaType.APPLICATION_JSON)
  @Consumes(MediaType.APPLICATION_JSON)
  public ClientRepresentation regenerateRegistrationAccessToken() {
    auth.requireManage();

    if (client == null) {
      throw new NotFoundException("Could not find client");
    }

    String token =
        ClientRegistrationTokenUtils.updateRegistrationAccessToken(
            session, realm, uriInfo, client, RegistrationAuth.AUTHENTICATED);

    ClientRepresentation rep = ModelToRepresentation.toRepresentation(client);
    rep.setRegistrationAccessToken(token);

    adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(rep).success();
    return rep;
  }
Exemple #7
0
  public void updateClientFromRep(
      ClientRepresentation rep, ClientModel client, KeycloakSession session)
      throws ModelDuplicateException {
    if (TRUE.equals(rep.isServiceAccountsEnabled()) && !client.isServiceAccountsEnabled()) {
      new ClientManager(new RealmManager(session)).enableServiceAccount(client);
    }

    if (!rep.getClientId().equals(client.getClientId())) {
      new ClientManager(new RealmManager(session)).clientIdChanged(client, rep.getClientId());
    }

    RepresentationToModel.updateClient(rep, client);

    if (Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
      if (TRUE.equals(rep.getAuthorizationServicesEnabled())) {
        authorization().enable();
      } else {
        authorization().disable();
      }
    }
  }
  @Before
  public void addClients() {
    List<ClientRepresentation> clients = bc.createProviderClients(suiteContext);
    if (clients != null) {
      RealmResource providerRealm = adminClient.realm(bc.providerRealmName());
      for (ClientRepresentation client : clients) {
        log.debug("adding client " + client.getName() + " to realm " + bc.providerRealmName());

        providerRealm.clients().create(client);
      }
    }

    clients = bc.createConsumerClients(suiteContext);
    if (clients != null) {
      RealmResource consumerRealm = adminClient.realm(bc.consumerRealmName());
      for (ClientRepresentation client : clients) {
        log.debug("adding client " + client.getName() + " to realm " + bc.consumerRealmName());

        consumerRealm.clients().create(client);
      }
    }
  }
Exemple #9
0
  /**
   * Should not be called from an import. This really expects that the client is created from the
   * admin console.
   *
   * @param session
   * @param realm
   * @param rep
   * @param addDefaultRoles
   * @return
   */
  public static ClientModel createClient(
      KeycloakSession session,
      RealmModel realm,
      ClientRepresentation rep,
      boolean addDefaultRoles) {
    ClientModel client = RepresentationToModel.createClient(session, realm, rep, addDefaultRoles);

    if (rep.getProtocol() != null) {
      LoginProtocolFactory providerFactory =
          (LoginProtocolFactory)
              session
                  .getKeycloakSessionFactory()
                  .getProviderFactory(LoginProtocol.class, rep.getProtocol());
      providerFactory.setupClientDefaults(rep, client);
    }

    // remove default mappers if there is a template
    if (rep.getProtocolMappers() == null && rep.getClientTemplate() != null) {
      Set<ProtocolMapperModel> mappers = client.getProtocolMappers();
      for (ProtocolMapperModel mapper : mappers) client.removeProtocolMapper(mapper);
    }
    return client;
  }
Exemple #10
0
 public static Auth token(ClientRepresentation client) {
   return new BearerTokenAuth(client.getRegistrationAccessToken());
 }
Exemple #11
0
  @Test
  public void addUserTest() throws Throwable {
    AddUser.main(new String[] {"-u", "addusertest-admin", "-p", "password"});
    assertEquals(1, dir.listFiles().length);

    List<RealmRepresentation> realms =
        JsonSerialization.readValue(
            new FileInputStream(new File(dir, "keycloak-add-user.json")),
            new TypeReference<List<RealmRepresentation>>() {});
    assertEquals(1, realms.size());
    assertEquals(1, realms.get(0).getUsers().size());

    UserRepresentation user = realms.get(0).getUsers().get(0);
    assertEquals(new Integer(100000), user.getCredentials().get(0).getHashIterations());
    assertNull(user.getCredentials().get(0).getValue());

    CredentialRepresentation credentials = user.getCredentials().get(0);

    assertEquals(Pbkdf2PasswordHashProvider.ID, credentials.getAlgorithm());
    assertEquals(new Integer(100000), credentials.getHashIterations());

    KeycloakServer server = new KeycloakServer();
    try {
      server.start();

      Keycloak keycloak =
          Keycloak.getInstance(
              "http://localhost:8081/auth",
              "master",
              "addusertest-admin",
              "password",
              Constants.ADMIN_CLI_CLIENT_ID);
      keycloak.realms().findAll();

      RealmRepresentation testRealm = new RealmRepresentation();
      testRealm.setEnabled(true);
      testRealm.setId("test");
      testRealm.setRealm("test");

      keycloak.realms().create(testRealm);

      RealmResource realm = keycloak.realm("master");

      List<UserRepresentation> users =
          realm.users().search("addusertest-admin", null, null, null, null, null);
      assertEquals(1, users.size());

      UserRepresentation created = users.get(0);
      assertNotNull(created.getCreatedTimestamp());

      UserResource userResource = realm.users().get(created.getId());

      List<RoleRepresentation> realmRoles = userResource.roles().realmLevel().listAll();

      assertRoles(realmRoles, "admin", "offline_access");

      List<ClientRepresentation> clients = realm.clients().findAll();
      String accountId = null;
      for (ClientRepresentation c : clients) {
        if (c.getClientId().equals("account")) {
          accountId = c.getId();
        }
      }

      List<RoleRepresentation> accountRoles = userResource.roles().clientLevel(accountId).listAll();

      assertRoles(accountRoles, "view-profile", "manage-account");

      keycloak.close();

      assertEquals(0, dir.listFiles().length);
    } finally {
      server.stop();
    }
  }
Exemple #12
0
  @Test
  public void testUpdateThoroughly() throws IOException {

    FileConfigHandler handler = initCustomConfigFile();

    try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) {

      final String realm = "test";

      loginAsUser(configFile.getFile(), serverUrl, realm, "user1", "userpass");

      // create an object so we can update it
      KcRegExec exe =
          execute("create --config '" + configFile.getName() + "' -o -s clientId=my_client");

      assertExitCodeAndStdErrSize(exe, 0, 0);

      ClientRepresentation client =
          JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);

      Assert.assertEquals("enabled", true, client.isEnabled());
      Assert.assertEquals("publicClient", false, client.isPublicClient());
      Assert.assertEquals("bearerOnly", false, client.isBearerOnly());
      Assert.assertTrue("redirectUris is empty", client.getRedirectUris().isEmpty());

      // Merge update
      exe =
          execute(
              "update my_client --config '"
                  + configFile.getName()
                  + "' -o "
                  + " -s enabled=false -s 'redirectUris=[\"http://localhost:8980/myapp/*\"]'");

      assertExitCodeAndStdErrSize(exe, 0, 0);

      client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
      Assert.assertEquals("enabled", false, client.isEnabled());
      Assert.assertEquals(
          "redirectUris", Arrays.asList("http://localhost:8980/myapp/*"), client.getRedirectUris());

      // Another merge update - test deleting an attribute, deleting a list item and adding a list
      // item
      exe =
          execute(
              "update my_client --config '"
                  + configFile.getName()
                  + "' -o -d redirectUris -s webOrigins+=http://localhost:8980/myapp -s webOrigins+=http://localhost:8981/myapp -d webOrigins[0]");

      assertExitCodeAndStdErrSize(exe, 0, 0);

      client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);

      Assert.assertTrue("redirectUris is empty", client.getRedirectUris().isEmpty());
      Assert.assertEquals(
          "webOrigins", Arrays.asList("http://localhost:8981/myapp"), client.getWebOrigins());

      // Another merge update - test nested attributes and setting an attribute using json format
      // TODO KEYCLOAK-3705 Updating protocolMapper config via client registration endpoint has no
      // effect
      /*
      exe = execute("update my_client --config '" + configFile.getName() + "' -o -s 'protocolMappers[0].config.\"id.token.claim\"=false' " +
              "-s 'protocolMappers[4].config={\"single\": \"true\", \"attribute.nameformat\": \"Basic\", \"attribute.name\": \"Role\"}'");

      assertExitCodeAndStdErrSize(exe, 0, 0);

      client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
      Assert.assertEquals("protocolMapper[0].config.\"id.token.claim\"", "false", client.getProtocolMappers().get(0).getConfig().get("id.token.claim"));
      Assert.assertEquals("protocolMappers[4].config.single", "true", client.getProtocolMappers().get(4).getConfig().get("single"));
      Assert.assertEquals("protocolMappers[4].config.\"attribute.nameformat\"", "Basic", client.getProtocolMappers().get(4).getConfig().get("attribute.nameformat"));
      Assert.assertEquals("protocolMappers[4].config.\"attribute.name\"", "Role", client.getProtocolMappers().get(4).getConfig().get("attribute.name"));
      */

      // update using oidc format

      // check that using an invalid attribute key is not ignored
      exe = execute("update my_client --nonexisting --config '" + configFile.getName() + "'");

      assertExitCodeAndStreamSizes(exe, 1, 0, 2);
      Assert.assertEquals(
          "error message", "Unsupported option: --nonexisting", exe.stderrLines().get(0));
      Assert.assertEquals(
          "try help",
          "Try '" + CMD + " help update' for more information",
          exe.stderrLines().get(1));

      // try use incompatible endpoint
      exe =
          execute(
              "update my_client --config '"
                  + configFile.getName()
                  + "' -o -s enabled=true -e oidc");

      assertExitCodeAndStreamSizes(exe, 1, 0, 1);
      Assert.assertEquals(
          "error message",
          "Failed to set attribute 'enabled' on document type 'oidc'",
          exe.stderrLines().get(0));

      // test overwrite from file
      exe =
          KcRegExec.newBuilder()
              .argsLine(
                  "update my_client --config '"
                      + configFile.getName()
                      + "' -o  -s clientId=my_client -s 'redirectUris=[\"http://localhost:8980/myapp/*\"]' -f -")
              .stdin(new ByteArrayInputStream("{ \"enabled\": false }".getBytes()))
              .execute();

      assertExitCodeAndStdErrSize(exe, 0, 0);

      client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
      // web origin is not sent to the server, thus it retains the current value
      Assert.assertEquals(
          "webOrigins", Arrays.asList("http://localhost:8981/myapp"), client.getWebOrigins());
      Assert.assertFalse("enabled is false", client.isEnabled());
      Assert.assertEquals(
          "redirectUris", Arrays.asList("http://localhost:8980/myapp/*"), client.getRedirectUris());

      // test using merge with file
      exe =
          KcRegExec.newBuilder()
              .argsLine(
                  "update my_client --config '"
                      + configFile.getName()
                      + "' -o -s enabled=true -m -f -")
              .stdin(
                  new ByteArrayInputStream(
                      "{ \"webOrigins\": [\"http://localhost:8980/myapp\"] }".getBytes()))
              .execute();

      assertExitCodeAndStdErrSize(exe, 0, 0);

      client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
      Assert.assertEquals(
          "webOrigins", Arrays.asList("http://localhost:8980/myapp"), client.getWebOrigins());
      Assert.assertTrue("enabled is true", client.isEnabled());
      Assert.assertEquals(
          "redirectUris", Arrays.asList("http://localhost:8980/myapp/*"), client.getRedirectUris());

      // remove registration access token
      exe =
          execute(
              "config registration-token --config '"
                  + configFile.getName()
                  + "' --server "
                  + serverUrl
                  + " --realm "
                  + realm
                  + " --client my_client -d");

      assertExitCodeAndStdErrSize(exe, 0, 0);

      Assert.assertNull(
          "my_client registration token",
          handler
              .loadConfig()
              .ensureRealmConfigData(serverUrl, realm)
              .getClients()
              .get("my_client"));
    }
  }