Package com.inrupt.client.openid


package com.inrupt.client.openid

OpenID support for the Inrupt Java Client Libraries.

This module uses the OpenIdProvider to interact with a OpenId Provider as described in the Solid-OIDC Primer v 0.1.0

OpenIdProvider helps in the interaction with the token endpoint and to construct helper requests for authentication.

Discovering the openID configuration


   Client client = ClientProvider.getClient();
   OpenIdProvider openIdProvider = new OpenIdProvider(URI.create("https://issuer.example"), client));

   Metadata opConfig = openIdProvider.metadata();

   System.out.println("Authorization endpoint is: " + opConfig.authorizationEndpoint.toString());
   System.out.println("Token endpoint is: " + opConfig.tokenEndpoint.toString());
 

Creating an AuthorizationRequest (needed for browser-based authorization code flow)


   Client client = ClientProvider.getClient();

   AuthorizationRequest authReq = AuthorizationRequest.newBuilder()
      .responseType("code") //required response_type
      .scope(List.of("openid", "webid", "offline_access")) //required scope
      .build(
            "s6BhdRkqt3", //required client_id
            URI.create("https://example.example/callback"); //required redirect_uri

   Request authorizationRequest = Request.newBuilder()
            .uri(URI.create(openIdProvider.authorize(authReq)))
            .GET()
            .build();

   Response authorizationResponse = client.send(authorizationRequest, Response.BodyHandlers.ofString())
                                    .toCompletableFuture().join();
 

Obtaining an ID token


   TokenRequest tokenReq = TokenRequest.newBuilder()
            .code("code")
            .codeVerifier("myCodeverifier")
            .redirectUri(URI.create("https://app.example/callback"))
            .clientSecret("myClientSecret")
            .authMethod("client_secret_basic")
            .build(
                "authorization_code",
                "s6BhdRkqt3") //same client_id as from the authorization
            );
   TokenResponse token = openIdProvider.token(tokenReq).toCompletableFuture().join();

   System.out.println("ID Token: " + token.idToken);
   System.out.println("Token type: " + token.tokenType);
 

If we already have a session, we can use it with the ID Tokens serialized as signed JWTs. This abstraction can be used to make use of identity-based authorization in Solid.


   Client client = ClientProvider.getClient();
   Session session = client.session(OpenIdSession.ofIdToken(jwt));
   Response res = session.send(req, bodyHandler).toCompletableFuture().join();
 

A developer can configure aspects of the ID Token validation. All tokens require the presence of subject (sub) and issuer (iss) claims as well as issued at (iat) and expiration (exp) claims. By default, signature verification is not enabled, but it can be turned on via configuration, as can audience verification.


   Client client = ClientProvider.getClient();

   OpenIdConfig config = new OpenIdConfig();
   config.setExpectedAudience("https://app.example/id");
   config.setPublicKeyLocation("https://issuer.example/jwks");
   config.setExpGracePeriodSecs(60);

   Session session = client.session(OpenIdSession.ofIdToken(jwt, config));

   Response res = session.send(req, bodyHandler).toCompletableFuture().join();
 

An invalid token will throw an OpenIdException during session creation.

Ending the session.


   EndSessionRequest endReq = EndSessionRequest.Builder.newBuilder()
         .postLogoutRedirectUri(URI.create("https://example.example/callback")) //redirect_uri
         .clientId("s6BhdRkqt3") //client_id
         .state("code")
         .build();

   URI uri = openIdProvider.endSession(endReq).toCompletableFuture().join();
 

Generating a PKCE code challenge and verifier.

The default challenge encoding is SHA-256. Pass an algorithm to createChallenge if another encoding is required.


   String verifier = PKCE.createVerifier();
   String challenge = PKCE.createChallenge(verifier);