The Okta Authentication SDK is a convenience wrapper around Okta's Authentication API.
NOTE: Using an OAuth 2.0 or OIDC to integrate your application instead of this library will require much less work, and has a smaller risk profile. Please see this guide to see if using this API is right for your use case. You could also use our Spring Boot Integration, or Spring Security out of the box.
Okta's Authentication API is built around a state machine. In order to use this library you will need to be familiar with the available states. You will need to implement a handler for each state you want to support.
You can see this project's Javadocs at https://developer.okta.com/okta-authn-java/
The only compile time dependency you will need is okta-authn-sdk-api
. You will also need to add the implementation dependencies too: okta-authn-sdk-impl
and okta-sdk-httpclient
.
<dependency>
<groupId>com.okta.sdk</groupId>
<artifactId>okta-authn-sdk-api</artifactId>
<version>${okta.authn.version}</version>
</dependency>
<dependency>
<groupId>com.okta.sdk</groupId>
<artifactId>okta-authn-sdk-impl</artifactId>
<version>${okta.authn.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.okta.sdk</groupId>
<artifactId>okta-sdk-httpclient</artifactId>
<version>${okta.sdk.version}</version>
<scope>runtime</scope>
</dependency>
Snapshots are deployed off of the 'master' branch to OSSRH and can be consumed using the following repository configured for Apache Maven or Gradle:
https://oss.sonatype.org/content/repositories/snapshots/
There are a few ways to configure the client, but the easiest way is to create a ~/.okta/okta.yaml
file and orgUrl
value:
okta:
client:
orgUrl: https://dev-123456.oktapreview.com
Once you create your okta.yaml
file, you can create a client with a couple of lines:
// Instantiate a builder for your client. If needed, settings like Proxy and connection timeouts can be defined here.
AuthenticationClientBuilder builder = AuthenticationClients.builder();
// No need to define anything else; build the AuthenticationClient instance.
AuthenticationClient client = builder.build();
For more details see: Creating a Client
An authentication flow usually starts with a call to authenticate
:
// could be where to redirect when authentication is done, a token, or null
String relayState = "/application/specific";
client.authenticate(username, password, relayState, stateHandler);
Everything looks pretty standard except for stateHandler
. The AuthenticationStateHandler
is a mechanism to fire an event for the given authentication state returned. Basically, it prevents you from needing to use something like a switch statement to check state of the AuthenticationResponse
.
A typical AuthenticationStateHandler
may look something like:
public class ExampleAuthenticationStateHandler extends AuthenticationStateHandlerAdapter {
@Override
public void handleUnknown(AuthenticationResponse unknownResponse) {
// redirect to "/error"
}
@Override
public void handleSuccess(AuthenticationResponse successResponse) {
// a user is ONLY considered authenticated if a sessionToken exists
if (Strings.hasLength(successResponse.getSessionToken())) {
String relayState = successResponse.getRelayState();
String dest = relayState != null ? relayState : "/";
// redirect to dest
}
// other state transition successful
}
@Override
public void handlePasswordExpired(AuthenticationResponse passwordExpired) {
// redirect to "/login/change-password"
}
// Other implemented states here
}
As noted in the above example, a user is ONLY considered authenticated if AuthenticationResponse.getSessionToken()
is not null. This sessionToken
can be exchanged via the Okta Sessions API to start an SSO session, but that is beyond the scope of this library.
NOTE: UNKNOWN
is not an actual state in Okta's Authentication state model. The method handleUnknown
is called when an unimplemented state is reached (this could happen if someone turned on MFA support for your Okta organization but was not previously implemented in your state handler). It also possible Okta has added a new state to the state model, and someone from your organization enabled this new state.
Take a look at the (contribution guide)[CONTRIBUTING.md] and the build instructions wiki (though just cloning the repo and running mvn install
should get you going).