All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.stormpath.sdk.oauth.OauthRequestAuthenticator Maven / Gradle / Ivy

Go to download

The Stormpath Java SDK API .jar provides a Java API that your code can use to make calls to the Stormpath API. This .jar is the only compile-time dependency within the Stormpath SDK project that your code should depend on. Implementations of this API (implementation .jars) should be runtime dependencies only.

There is a newer version: 2.0.4-okta
Show newest version
/*
 * Copyright 2014 Stormpath, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stormpath.sdk.oauth;

import com.stormpath.sdk.api.ApiRequestAuthenticator;
import com.stormpath.sdk.http.HttpRequest;

/**
 * An OAuth-specific {@code ApiRequestAuthenticator} that implements the
 * Builder design pattern to allow customization of how
 * the authentication attempt is processed.  For example:
 *
 * 
 * AuthenticationResult result = {@link com.stormpath.sdk.application.Application#authenticateOauthRequest(Object)
 * application.authenticateOauthRequest(httpRequest)}
 *     {@link #using(ScopeFactory) .using(scopeFactory)}
 *     {@link #withTtl(long) .withTtl(3600)}
 *     {@link #execute() .execute()};
 * 
* * @see com.stormpath.sdk.application.Application#authenticateOauthRequest(Object) * @see #execute() * @since 1.0.RC */ public interface OauthRequestAuthenticator extends ApiRequestAuthenticator { /** * Specifies the {@link ScopeFactory} to be used when generating a new Access Token as a result of authenticating * the OAuth request. * *

This method should only be called when the OAuth client is specifically requesting a new Access Token, * for example, a request to your application's oauth token endpoint, e.g. {@code /oauth/token}

* * @param scopeFactory the {@link ScopeFactory} to be used for this authentication request. * @return a new {@link AccessTokenRequestAuthenticator} instance created with the current state of the * this builder. */ AccessTokenRequestAuthenticator using(ScopeFactory scopeFactory); /** * Specifies the time to live of this authentication request * in seconds. If not specified, the default value is {@code 3600} (seconds) - i.e. 1 hour. * *

This method should only be called when the OAuth client is specifically requesting a new Access Token, * for example, a request to your application's oauth token endpoint, e.g. {@code /oauth/token}

* * @param ttl the time to live (in seconds) of this authentication request. * @return a new {@link AccessTokenRequestAuthenticator} instance created with the current state of the * this builder. */ AccessTokenRequestAuthenticator withTtl(long ttl); /** * Specifies the request location(s) that will be checked when looking up the request's Access Token. Unspecified * locations will not be checked. *

* If this method is not called, both the request header and body will be checked by default. *

* *

This method will return a new {@link ResourceRequestAuthenticator} with the current state of the this * builder.

* * @param locations the location(s) for the Bearer. * @return a new {@link ResourceRequestAuthenticator} instance created with the current state of the * this builder. */ ResourceRequestAuthenticator inLocation(RequestLocation... locations); /** * Executes this authentication request. * * @return the result of the authentication request in the form of a {@link OauthAuthenticationResult}. * @deprecated this method will be removed soon. Use {@link OauthRequestAuthenticator#authenticate(HttpRequest)} instead */ @Deprecated OauthAuthenticationResult execute(); /** * Authenticates an OAuth-based HTTP request submitted to your application's API, returning a result that * reflects the successfully authenticated {@link com.stormpath.sdk.account.Account} that made the request and the {@link com.stormpath.sdk.api.ApiKey} used to * authenticate the request. Throws a {@link com.stormpath.sdk.resource.ResourceException} if the request cannot be authenticated. * *

This method is only useful if you know for sure the HTTP request is an Oauth-based request, and: * *

    *
  • * The request is authenticating with an Access Token and you want to explicitly control the * locations in the request where you allow the access token to exist. If you're comfortable with the default * behavior of inspecting the headers and request body (and not request params, as they can be seen as a less * secure way of authentication), you do not need to call this method, and should call the * ServletApi method instead. *
  • *
  • *

    The HTTP request is an OAuth Client Credentials Grant Type request whereby the client is explicitly * asking for a new Access Token and you want to control the returned token's OAuth scope and/or * time-to-live (TTL).

    *

    This almost always is the case when the client is interacting with your * OAuth token endpoint, for example, a URI like {@code /oauth2/tokens}. If either the request is a normal OAuth * request or the above condition does not apply to you, then you do not need to call this method, and * should call the {@link ApiRequestAuthenticator#authenticate(HttpRequest)} method instead.

    *
  • *
*

Again, if either of these two scenarios above does not apply to your use case, do not call this method; call * the {@link ApiRequestAuthenticator#authenticate(HttpRequest)} method instead.

* *

Next, we'll cover these 2 scenarios.

* *

Scenario 1: OAuth (Bearer) Access Token Allowed Locations

* *

By default, this method and {@link ApiRequestAuthenticator#authenticate(HttpRequest)} will authenticate an OAuth request * that presents its (bearer) Access Token in two of three locations in the request: *

    *
  1. * The request's {@code Authorization} header, per the * OAuth 2 Bearer Token specification, Section * 2.1. *
  2. *
  3. * The request {@code application/x-www-form-urlencoded} body as a {@code access_token} parameter, per the * OAuth 2 Bearer Token specification, Section * 2.2 *
  4. *
*

*

* Although checking a request {@code access_token} query parameter, per the * OAuth 2 Bearer Token specification, Section 2.3 is * also supported, query parameters are NOT inspected by default. Using request parameters for * authentication is often seen as a potential security risk and generally discouraged. That being said, if you * need to support this location, perhaps because you need to support a legacy client, you can enable this * location explicitly if desired, for example: *

     * import static com.stormpath.sdk.oauth.RequestLocation.*;
     *
     * Application application = client.getResource(myApplicationRestUrl, Application.class);
     *
     * OAuthAuthenticationResult result = Applications.oauthRequestAuthenticator(application)
     *     {@link OauthRequestAuthenticator#inLocation(com.stormpath.sdk.oauth.RequestLocation...) .inLocation(}{@link com.stormpath.sdk.oauth.RequestLocation#HEADER HEADER}, {@link com.stormpath.sdk.oauth.RequestLocation#BODY BODY}, {@link com.stormpath.sdk.oauth.RequestLocation#QUERY_PARAM QUERY_PARAM})
     *     .authenticate(httpRequest);
     * 
*

* *

The above code example implies that you will tell developers which options they * may use (and may not use) when configuring their OAuth client to communicate with your API.

* *

Scenario 2: Creating OAuth Access Tokens

* *

If the HTTP request is sent to your OAuth token creation endpoint, for example, {@code /oauth2/token} you * will need to call this method, and the Stormpath SDK will automatically create an Access Token for you. After * it is created, you must send the token to the client in the HTTP response. For example: * *

     * //assume a POST request to, say, https://api.mycompany.com/oauth/token:
     *
     * public void processOauthTokenRequest(HttpServletRequest request, HttpServletResponse response) {
     *
     *    Application application = client.getResource(myApplicationRestUrl, Application.class);
     *
     *    AccessTokenResult result = (AccessTokenResult) Applications.oauthRequestAuthenticator(application).authenticate(request);
     *
     *    TokenResponse token = result.getTokenResponse();
     *
     *    response.setStatus(HttpServletResponse.SC_OK);
     *    response.setContentType("application/json");
     *    response.getWriter().print(token.toJson());
     *
     *    response.getWriter().flush();
     * }
     * 
*

* *

As you can see, {@link com.stormpath.sdk.oauth.TokenResponse#toJson() tokenResponse.toJson()} method * will return a JSON string to populate the response body - it is not strictly * necessary to read individual properties on the {@code TokenResponse} instance.

* *

Non Servlet Environments

* *

If your application does not run in a Servlet environment - for example, maybe you use a custom HTTP * framework, or Netty, or Play!, you can use the {@link com.stormpath.sdk.http.HttpRequestBuilder * HttpRequestBuilder} to represent your framework-specific HTTP request object as a type the Stormpath SDK * understands. For example:

*
     * ...
     * // Convert the framework-specific HTTP Request into a request type the Stormpath SDK understands:
     *    {@link com.stormpath.sdk.http.HttpRequest HttpRequest} request = {@link com.stormpath.sdk.http.HttpRequests HttpRequests}.method(frameworkSpecificRequest.getMethod())
     *        .headers(frameworkSpecificRequest.getHeaders())
     *        .queryParameters(frameworkSpecificRequest.getQueryParameters())
     *        .build();
     *
     *    ApiAuthenticationResult result = Applications.oauthRequestAuthenticator(application).authenticate(request);
     * ...
     * 
* *

Customizing the OAuth Access Token Time-To-Live (TTL)

* *

By default, this SDK creates Access Tokens that are valid for 3600 seconds (1 hour). If you want to change * this value, you will need to invoke the {@code withTtl} method on the returned executor and specify your desired * TTL. For example: * *

     * //assume a POST request to, say, https://api.mycompany.com/oauth/token:
     *
     * public void processOauthTokenRequest(HttpServletRequest request, HttpServletResponse response) {
     *
     *    Application application = client.getResource(myApplicationRestUrl, Application.class);
     *
     *    int desiredTimeoutSeconds = 3600; //change to your preferred value
     *
     *    AccessTokenResult result = (AccessTokenResult) Applications.oauthRequestAuthenticator(application)
     *      .withTtl(desiredTimeoutSeconds)
     *      .authenticate(request);
     *
     *    TokenResponse token = result.getTokenResponse();
     *
     *    response.setStatus(HttpServletResponse.SC_OK);
     *    response.setContentType("application/json");
     *    response.getWriter().print(token.toJson());
     *
     *    response.getWriter().flush();
     * }
     * 
*

* *

Customizing the OAuth Access Token Scope

* *

As an Authorization protocol, OAuth allows you to attach scope, aka application-specific * permissions to an Access Token when it is created. You can check this scope on * {@link ApiRequestAuthenticator#authenticate(HttpRequest)} later requests} and make authorization decisions to allow or deny the API * request based on the granted scope.

* *

When an access token is created, you can specify your application's own custom scope by calling the * {@code withScope} method on the returned executor. For example: * *

     * //assume a POST request to, say, https://api.mycompany.com/oauth/token:
     *
     * public void processOauthTokenRequest(HttpServletRequest request, HttpServletResponse response) {
     *
     *    Application application = client.getResource(myApplicationRestUrl, Application.class);
     *
     *    int desiredTimeoutSeconds = 3600; //change to your preferred value
     *
     *    ScopeFactory scopeFactory = getScopeFactory(); //get your ScopeFactory implementation from your app config
     *
     *    AccessTokenResult result = (AccessTokenResult)application
     *        .authenticateOauthRequest(request)
     *        .withTtl(desiredTimeoutSeconds)
     *        .withScopeFactory(scopeFactory)
     *        .authenticate(request);
     *
     *    TokenResponse token = result.getTokenResponse();
     *
     *    response.setStatus(HttpServletResponse.SC_OK);
     *    response.setContentType("application/json");
     *    response.getWriter().print(token.toJson());
     *
     *    response.getWriter().flush();
     * }
     * 
*

* *

Your {@link com.stormpath.sdk.oauth.ScopeFactory ScopeFactory} implementation can inspect the * 1) successfully authenticated API client Account and 2) the client's requested scope. Your * implementation returns the actual scope that you want granted to the Access Token (which may or may not * be different than the requested scope based on your requirements).

* * @param httpRequest a {@link com.stormpath.sdk.http.HttpRequest} instance. * @return a new {@link OauthAuthenticationResult} if the API request was authenticated successfully. * @throws IllegalArgumentException if the method argument is null or is not either a {@link com.stormpath.sdk.http.HttpRequest} instance. * @see ApiRequestAuthenticator#authenticate(com.stormpath.sdk.http.HttpRequest) * * @since 1.0.RC4.6 */ OauthAuthenticationResult authenticate(HttpRequest httpRequest); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy