Okta Java Management SDK

repository·master·Indexed 41 days ago

https://github.com/okta/okta-sdk-java

A type-safe server-side library for Java 11+ to interact with the Okta Management API. It enables programmatic control over users, groups, applications, security factors, and organizational configurations. The SDK supports API token and OAuth 2.0 (Private Key) authentication, integrates with Spring Boot via okta-spring-sdk, and provides built-in caching and retry strategies. Latest stable major version series is 25.x.x.

Tokens
16.3K
Snippets
36
Records
71
Agent score
51%

What's inside Okta Java SDK

  1. Overview of the Okta Java Management SDK

    master

    The Okta Java Management SDK is a server-side library used to interact with the Okta management API. It allows developers to programmatically manage various Okta resources including users, groups, applications, security factors, logs, sessions, and more.

    Key capabilities include:

    • User Management: Create, update, and manage user profiles, risk levels, and classification.
    • Security & Access: Manage security factors, authenticator enrollments, and identity providers.
    • Organization Management: Manage groups, applications, custom domains, network zones, and trusted origins.
    • System & Automation: Manage logs, event hooks, inline hooks, and authorization servers.
  2. How pagination and thread safety work in the SDK

    master

    The SDK provides two ways to fetch collections, but they differ significantly in thread safety and ease of use:

    1. *Paged() methods (Recommended): These return a PagedIterable which provides lazy, memory-efficient iteration with automatic pagination. This approach is thread-safe; each iterator maintains its own state independently, making it safe to use across multiple threads.
    2. list*() methods: These perform a single-page fetch. They are suitable for simple use cases where you only need the first page of results.

    Warning on Legacy Pagination: The PaginationUtil.getAfter() approach is deprecated and will be removed in v26.0.0. It relies on thread-local state, which can cause state leakage and warnings in multi-threaded environments (specifically when more than 3 threads access the same ApiClient). Always prefer *Paged() methods.

    // Recommended: Thread-safe, automatic pagination
    PagedIterable<User> users = userApi.listUsersPagedIterable(null, null, 200, null, null, null, null);
    for (User user : users) {
        System.out.println(user.getProfile().getLogin());
    }
  3. Configure Caching

    master

    The SDK includes a production-grade in-memory CacheManager by default. It features a 1-hour TTL/TTI and auto-sizes to prevent OutOfMemoryExceptions.

    Warning: The default in-memory cache is not suitable for applications deployed across multiple JVMs (e.g., scaled web clusters). In such cases, you must provide a distributed/clustered CacheManager implementation.

    Customizing In-Memory Cache (Single JVM)

    You can define specific TTL/TTI settings for different resource types using Caches.newCacheManager().

    Disabling Caching

    To disable caching entirely, use Caches.newDisabledCacheManager() during client construction.

    // Customizing cache settings for specific resources
    Caches.newCacheManager()
        .withDefaultTimeToLive(300, TimeUnit.SECONDS)
        .withDefaultTimeToIdle(300, TimeUnit.SECONDS)
        .withCache(forResource(User.class)
            .withTimeToLive(1, TimeUnit.HOURS)
            .withTimeToIdle(30, TimeUnit.MINUTES))
        .withCache(forResource(Group.class)
            .withTimeToLive(1, TimeUnit.HOURS))
        .build();
    
    // Disabling caching
    ApiClient client = Clients.builder()
        .setCacheManager(Caches.newDisabledCacheManager())
        .build();
  4. Configure Connection Retries

    master

    The SDK automatically retries requests that return 503, 504, 429 (rate limiting), or encounter socket/connection exceptions.

    Retry Strategies

    1. Interactive Clients (e.g., Web Pages) Optimal for low latency. Set a low requestTimeout and disable retries (maxRetries = 0) to ensure the request fails quickly if it cannot succeed within the window.

    2. Batch/Non-Interactive Processes Optimal for background tasks. Set requestTimeout to 0 (no limit) and increase maxRetries to allow the process to wait out rate limits or transient errors.

    3. Hybrid Approach Limit both execution time and attempts by setting both values.

    Configuration Keys

    • okta.client.requestTimeout: Maximum seconds to wait when retrying before giving up. (Note: For 429 errors, the SDK caps the sleep time to this value or a 20-second default ceiling).
    • okta.client.rateLimit.maxRetries: Maximum number of retry attempts.
    // Example: Interactive client configuration
    import com.okta.sdk.client.Client;
    import com.okta.sdk.client.Clients;
    
    Client client = Clients.builder()
                    .setRetryMaxElapsed(10)
                    .setRetryMaxAttempts(0)
                    .build();
  5. Migrate User Management logic for v25.0.0

    master

    In v25.0.0, the User object no longer contains the type property or its sub-properties (such as created, createdBy, displayName, name, etc.) directly in API responses. This is a high-impact breaking change affecting endpoints like GET /api/v1/users, GET /api/v1/users/{id}, and group/device user listings.

    To retrieve type information, you must now use the UserTypeApi separately.

    // Before (v24.x)
    User user = userApi.getUser(userId);
    UserType type = user.getType();
    String typeId = type.getId();
    String typeName = type.getName();
    Boolean isDefault = type.getDefault();
    Date created = type.getCreated();
    String createdBy = type.getCreatedBy();
    
    // After (v25.0.0)
    User user = userApi.getUser(userId);
    // user.getType() may return null or different structure
    // Use UserTypeApi to get type information separately
    
    UserTypeApi userTypeApi = new UserTypeApi(client);
    List<UserType> types = userTypeApi.listUserTypes();
    // Find user's type from the types list or user's _links
  6. Migrate Policy status handling for v25.0.0

    master

    In v25.0.0, the status property for policies (endpoints like GET /api/v1/policies) has changed its type. Instead of a raw string, it now uses a specific enum type. You must use .getValue() on the status object to retrieve the underlying value.

    // Before (v24.x)
    PolicyApi policyApi = new PolicyApi(client);
    Policy policy = policyApi.getPolicy(policyId, null);
    String status = policy.getStatus(); // Was different type
    
    // After (v25.0.0)
    PolicyApi policyApi = new PolicyApi(client);
    Policy policy = policyApi.getPolicy(policyId, null);
    PolicyStatus status = policy.getStatus(); // Now uses enum type
    String statusValue = status.getValue();
  7. Migrate from 1.x.x to 2.0.0

    master

    Version 2.0.0 introduced several breaking changes, including method renames, signature changes, and the introduction of new enum types. Key changes include:

    • Factor Classes: All *Factor classes were renamed to *UserFactor (e.g., FactorList became UserFactorList).
    • Enums: Several properties that previously returned String now return specific enum types, such as com.okta.sdk.resource.group.GroupType for Group.getType() and com.okta.sdk.resource.role.RoleType for Role.getType()/setType().
    • Deprecated Classes: Several classes were moved to okta-commons-java and are deprecated in this SDK, including ClientCredentialsProvider, Proxy, and various com.okta.sdk.http.* and com.okta.sdk.lang.* utilities.

    Refer to specific package changes below for detailed method renames and signature updates.

  8. Initialize API clients

    master

    To use the SDK, first initialize an ApiClient instance. You can then pass this instance to the constructors of specific API area clients, such as UserApi, GroupApi, or ApplicationApi, to perform management tasks in those specific domains.

    // Example of passing client to an API area client
    UserApi userApi = new UserApi(client);
    GroupApi groupApi = new GroupApi(client);
    ApplicationApi applicationApi = new ApplicationApi(client);
  9. Migrate Application Credentials and JWKS access for v25.0.0

    master

    In v25.0.0, the GET /api/v1/apps/{appId}/credentials/jwks endpoint and related methods have changed property types and now use a polymorphic response. When listing JWKs, use the ListJwk200ResponseInner class to access key details.

    ApplicationCredentialsApi credApi = new ApplicationCredentialsApi(client);
    
    // List JWKs - now uses polymorphic response
    List<ListJwk200ResponseInner> jwks = credApi.listJwks(appId);
    for (ListJwk200ResponseInner jwk : jwks) {
        System.out.println("Key ID: " + jwk.getKid());
        System.out.println("Key Type: " + jwk.getKty());
        System.out.println("Use: " + jwk.getUse()); // "sig" or "enc"
        System.out.println("Status: " + jwk.getStatus());
    }
  10. How to write Spec tests for the test server

    master

    When writing integration tests against the okta/okta-test-server, you must use specific annotations to define scenarios and resource management.

    • @Scenario("name"): Defines the scenario name, allowing the test server to execute the correct list of scenarios.
    • @TestResources(groups = "..."): Defines which test resources should be automatically cleaned up before the test runs.
    @Test
    // This annotation defines the scenario name, this allows the tests server to be run with the correct list of scenarios
    @Scenario("list-groups")
    // This annotation defines which test resources to be cleaned up automatically before the test is run
    @TestResources(groups = "List Test Group")
    void listGroupsTest() {
       ...
    }
  11. Handle Forgot Password changes in v4.0.0

    master

    In version 4.0.0, the direct API method ForgotPasswordResponse apiV1UsersUserIdCredentialsForgotPasswordPost(String userId) in com.okta.sdk.client.Client has been removed.

    Instead, use the following methods on the User resource:

    • User.forgotPasswordGenerateOneTimeToken(Boolean sendEmail)
    • User.forgotPasswordGenerateOneTimeToken()
    • User.forgotPasswordSetNewPassword(UserCredentials userCredentials, Boolean sendEmail)
    • User.forgotPasswordSetNewPassword(UserCredentials userCredentials)
  12. Migrate from 6.x.x to 7.0.0: Identity Provider changes

    master

    In version 7.0.0, the handling of Identity Provider types changed from Enums to Strings.

    Package com.okta.sdk.resource.identity.provider.IdentityProvider

    • setType(String identityProvider) replaces setType(com.okta.sdk.resource.identity.provider.IdentityProvider$TypeEnum).
    • getType() now returns a String instead of com.okta.sdk.resource.identity.provider.IdentityProvider$TypeEnum.

    Package com.okta.sdk.resource.identity.provider.IdentityProviderBuilders

    • A new method ofType(java.lang.String) was introduced to allow constructing Identity Providers of type String.