Interface OAuthClientService

  • All Superinterfaces:
    AutoCloseable

    @NonNullByDefault
    public interface OAuthClientService
    extends AutoCloseable
    This is the service factory to produce a OAuth2 service client that authenticates using OAUTH2. This is a service factory pattern; the OAuthe2 service client is not shared between bundles.

    The basic uses of this OAuthClient are as follows:

    Use case 1 - For the full authorization code grant flow, as described in RFC 6749 section 4.1 https://tools.ietf.org/html/rfc6749#section-4.1

    • Method #getAuthorizationUrl(String, String, String) to get an authorization code url
    • Redirect the user-agent/ real user (outside scope of this client)
    • Method #extractAuthCodeFromAuthResponse(String) to verify and extract the authorization code from the response
    • Method #getAccessTokenResponseByAuthorizationCode(String, String) to get an access token (may contain optional refresh token) by authorization code extracted in above step.
    • Use the AccessTokenResponse in code
    • When access token is expired, see Use case 3 - refresh token.
    Use case 2 - For Resource Owner Password Credentials Grant, as described in RFC 6749 section 4.3 https://tools.ietf.org/html/rfc6749#section-4.3
    • Method #getAccessTokenByResourceOwnerPasswordCredentials(String, String, String) to get AccessTokenResponse (may contain optional refresh token) by username and password
    • Use the AccessTokenResponse in code
    • When access token is expired, Use #refreshToken() to get another access token
    Use case 3 - Refresh token
    • Method #refreshToken
    Use case 4 - Client Credentials. This is used to get the AccessToken by purely the client credential (ESH).
    • Method #getAccessTokenByClientCredentials(String)
    Use case 5 - Implicit Grant (RFC 6749 section 4.2). The implicit grant usually involves browser/javascript redirection flows.
    • Method #getAccessTokenByImplicit(String, String, String)
    Use case 6 - Import OAuth access token for data migration. Existing implementations may choose to migrate existing OAuth access tokens to be managed by this client.
    • Method #importAccessTokenResponse(AccessTokenResponse)
    Use case 7 - Get tokens - continue from Use case 1/2/4/5.
    • Method #getAccessTokenResponse()
    Author:
    Gary Tse - Initial contribution, Hilbrand Bouwkamp - Added AccessTokenRefreshListener, fixed javadoc warnings
    • Method Detail

      • getAuthorizationUrl

        String getAuthorizationUrl​(@Nullable String redirectURI,
                                   @Nullable String scope,
                                   @Nullable String state)
                            throws OAuthException
        Use case 1 Part (A) This call produces a URL which can be used during the Authorization Code Grant part (A). The OAuthClientService generate an authorization URL, which contains the HTTP query parameters needed for authorization code grant.
        Parameters:
        redirectURI - is the http request parameter which tells the oauth provider the URI to redirect the user-agent. This may/ may not be present as per agreement with the oauth provider. e.g. after the human user authenticate with the oauth provider by the browser, the oauth provider will redirect the browser to this redirectURL.
        scope - Specific scopes, if null the service specified scopes will be used
        state - If the state is not null, it will be added as the HTTP query parameter state=xxxxxxxx . If the state is null, a random UUID will be generated and added state=, the state will be assigned to the requestParams in this case.
        Returns:
        An authorization URL during the Authorization Code Grant with http request parameters filled in. e.g Produces an URL string like this: https://oauth.provider?response_type=code&client_id=myClientId&redirect_uri=redirectURI&scope=myScope&state=mySecureRandomState
        Throws:
        OAuthException - if authorizationUrl or clientId were not previously provided (null)
        See Also:
        Authorization Code Grant illustration - rfc6749 section-4.1, Concerning which parameters must be set and which ones are optional - rfc6749 section-4.1.1
      • extractAuthCodeFromAuthResponse

        String extractAuthCodeFromAuthResponse​(String redirectURLwithParams)
                                        throws OAuthException
        Use case 1 Part (C). Part (B) is not in this client. Part (B) is about redirecting the user and user-agent and is not in scope. This is a continuation of the flow of Authorization Code Grant, part (C).
        Parameters:
        redirectURLwithParams - This is the full redirectURI from Part (A), getAuthorizationUrl(String, String, String), but added with authorizationCode and state parameters returned by the oauth provider. It is encoded in application/x-www-form-urlencoded format as stated in RFC 6749 section 4.1.2. To quote from the RFC: HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
        Returns:
        AuthorizationCode This authorizationCode can be used in the call {#getOAuthTokenByAuthCode(String)}
        Throws:
        OAuthException - If the state from redirectURLwithParams does not exactly match the expectedState, or exceptions arise while parsing redirectURLwithParams.
        See Also:
        for part (A), Authorization Code Grant illustration - rfc6749 section-4.1
      • getAccessTokenByResourceOwnerPasswordCredentials

        AccessTokenResponse getAccessTokenByResourceOwnerPasswordCredentials​(String username,
                                                                             String password,
                                                                             @Nullable String scope)
                                                                      throws OAuthException,
                                                                             IOException,
                                                                             OAuthResponseException
        Use case 2 - Resource Owner Password Credentials This is for when the username and password of the actual resource owner (user) is known to the client (ESH).
        Parameters:
        username - of the user
        password - of the user
        scope - of the access, a space delimited separated list
        Returns:
        AccessTokenResponse
        Throws:
        IOException - IO/ network exceptions
        OAuthException - Other exceptions
        OAuthErrorException - Error codes given by authorization provider, as in RFC 6749 section 5.2 Error Response
        OAuthResponseException
        See Also:
        rfc6749 section-4.3.2
      • refreshToken

        AccessTokenResponse refreshToken()
                                  throws OAuthException,
                                         IOException,
                                         OAuthResponseException
        Use case 3 - refreshToken. Usually, it is only necessary to call #getAccessTokenResponse() directly. It automatically takes care of refreshing the token if the token has become expired. If the authorization server has invalidated the access token before the expiry, then this call can be used to get a new acess token by using the refresh token.
        Returns:
        new AccessTokenResponse from authorization server
        Throws:
        IOException - Web/ network issues etc.
        OAuthErrorException - For OAUTH error responses.
        OAuthException - For other exceptions.
        OAuthResponseException
        See Also:
        rfc6749 section-5.2
      • getAccessTokenByClientCredentials

        AccessTokenResponse getAccessTokenByClientCredentials​(@Nullable String scope)
                                                       throws OAuthException,
                                                              IOException,
                                                              OAuthResponseException
        Use case 4 - Client Credentials This is used to get the AccessToken by purely the client credential. The client in this context is the program making the call to OAuthClientService. The actual resource owner (human user) is not involved.
        Parameters:
        scope - of the access, a space delimited separated list
        Returns:
        AccessTokenResponse
        Throws:
        IOException - Web/ network issues etc.
        OAuthErrorException - For OAUTH error responses.
        OAuthException - For other exceptions.
        OAuthResponseException
      • getAccessTokenByImplicit

        AccessTokenResponse getAccessTokenByImplicit​(@Nullable String redirectURI,
                                                     @Nullable String scope,
                                                     @Nullable String state)
                                              throws OAuthException,
                                                     IOException,
                                                     OAuthResponseException
        Use case 5 - Implicit Grant The implicit grant usually involves browser/javascript redirection flows.
        Parameters:
        redirectURI - is the http request parameter which tells the oauth provider the URI to redirect the user-agent. This may/ may not be present as per agreement with the oauth provider. e.g. after the human user authenticate with the oauth provider by the browser, the oauth provider will redirect the browser to this redirectURL.
        scope - of the access, a space delimited separated list
        state - An opaque value used by the client to maintain state between the request and callback. Recommended to prevent cross-site forgery.
        Returns:
        AccessTokenResponse
        Throws:
        IOException - Web/ network issues etc.
        OAuthErrorException - For OAUTH error responses.
        OAuthException - For other exceptions.
        OAuthResponseException
        See Also:
        • importAccessTokenResponse

          void importAccessTokenResponse​(AccessTokenResponse accessTokenResponse)
                                  throws OAuthException
          Use case 6 - Import This method is used for importing/ migrating existing Access Token Response to be stored by this service.
          Parameters:
          accessTokenResponse -
          Throws:
          OAuthException - if client is closed
        • getAccessTokenResponse

          @Nullable AccessTokenResponse getAccessTokenResponse()
                                                        throws OAuthException,
                                                               IOException,
                                                               OAuthResponseException
          Use case 7 - get access token response. The tokens may have been retrieved previously through Use cases: 1d, 2, 3, 4, 6. The implementation uses following ways to get the AccesstokenResponse, in following order :-- 1. no token in store ==> return null 2. get from the store, token is still valid ==> return it. 3. get from the store, but token is expired, no refresh token ==> return null 4. get from the store, but token is expired, refresh token available ==> use refresh token to get new access token.
          Returns:
          AccessTokenResponse or null, depending on situations listed above.
          Throws:
          IOException - Web/ network issues etc.
          OAuthErrorException - For OAUTH error responses.
          OAuthException - For other exceptions.
          OAuthResponseException
        • remove

          void remove()
               throws OAuthException
          Remove all access token issued under this OAuthClientService. Use this to remove existing token or if the access and refresh token has become invalid/ invalidated.
          Throws:
          OAuthException - if client is closed
        • close

          void close()
          Stop the service and free underlying resources. This will not remove access tokens stored under the service.
          Specified by:
          close in interface AutoCloseable
        • isClosed

          boolean isClosed()
          The client cannot be used anymore if close has been previously called.
          Returns:
          true if client is closed. i.e. close() has been called.