001/*
002 * Copyright 2012-2016 UnboundID Corp.
003 *
004 * This program is free software; you can redistribute it and/or modify
005 * it under the terms of the GNU General Public License (GPLv2 only)
006 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
007 * as published by the Free Software Foundation.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU General Public License for more details.
013 *
014 * You should have received a copy of the GNU General Public License
015 * along with this program; if not, see <http://www.gnu.org/licenses>.
016 */
017
018package com.unboundid.scim.sdk;
019
020import java.security.GeneralSecurityException;
021
022
023/**
024 * This class defines an API that must be implemented by extensions which will
025 * handle incoming SCIM requests with OAuth 2.0 bearer token authentication.
026 * The OAuthTokenHandler is responsible for decoding the bearer token and
027 * checking it for authenticity and validity.
028 * <BR><BR>
029 * OAuth provides a method for clients to access a protected resource on
030 * behalf of a resource owner. In the general case, before a client can
031 * access a protected resource, it must first obtain an authorization
032 * grant from the resource owner and then exchange the authorization
033 * grant for an access token. The access token represents the grant's
034 * scope, duration, and other attributes specified by the authorization
035 * grant. The client accesses the protected resource by presenting the
036 * access token to the resource server (i.e. the Identity Data Store or Identity
037 * Proxy with the SCIM HTTP Servlet enabled).
038 * <BR><BR>
039 * The access token provides an abstraction, replacing different
040 * authorization constructs (e.g., username and password, assertion) for
041 * a single token understood by the resource server. This abstraction
042 * enables issuing access tokens valid for a short time period, as well
043 * as removing the resource server's need to understand a wide range of
044 * authentication schemes. See "OAuth 2.0 Authorization Framework: Bearer
045 * Token Usage" (<i>RFC 6750</i>) for the full
046 * specification and details.
047 * <BR><BR>
048 * TLS security is required to use OAuth 2.0 bearer tokens, as specified in
049 * <i>RFC 6750</i>. A bearer token may be used by any party
050 * in possession of that token (the "bearer"), and thus needs to be protected
051 * when transmitted across the network. Implementations of this API should take
052 * special care to verify that the token came from a trusted source (using a
053 * secret key or some other signing mechanism to prove that the token is
054 * authentic). Please read "OAuth 2.0 Threat Model and Security Considerations"
055 * (<i>RFC 6819</i>) for a comprehensive list of
056 * security threats to consider when working with OAuth bearer tokens.
057 * <BR><BR>
058 * The OAuthTokenHandler is also responsible for extracting an authorization DN
059 * from the bearer token (or otherwise providing one), which will be used to
060 * apply access controls before returning the protected resource. There are also
061 * methods to extract the expiration date of the token as well as verify that
062 * the intended audience is this server (to deal with token redirect).
063 * <BR><BR>
064 * The order these methods are called by the SCIM HTTP Servlet Extension is as
065 * follows:
066 * <ol>
067 *   <li><i>decodeOAuthToken()</i></li>
068 *   <li><i>isTokenAuthentic()</i></li>
069 *   <li><i>isTokenForThisServer()</i></li>
070 *   <li><i>isTokenExpired()</i></li>
071 *   <li><i>validateToken()</i></li>
072 *   <li><i>getAuthzDN()</i></li>
073 * </ol>
074 * If any of the methods fail or return an error result, the server will return
075 * an appropriate "unauthorized" response to the client.
076 */
077public interface OAuthTokenHandler
078{
079  /**
080   * Creates an {@link OAuthToken} instance from the incoming token value.
081   * <p>
082   * Implementers may choose to return a subclass of {@link OAuthToken} in
083   * order to provide convenience methods for interacting with the token. This
084   * can be helpful because the returned {@link OAuthToken} is passed to all of
085   * the other methods in this class.
086   *
087   * @param rawTokenValue the b64token token value. Note that b64token is just
088   *                      an ABNF syntax definition and does not imply any
089   *                      base64-encoding of the token value.
090   * @return a {@link OAuthToken} instance. This must not be {@code null}.
091   * @throws GeneralSecurityException if there is an error decoding the token
092   */
093  OAuthToken decodeOAuthToken(final String rawTokenValue)
094              throws GeneralSecurityException;
095
096
097
098  /**
099   * Determines whether the given token is expired.
100   *
101   * @param token the OAuth 2.0 bearer token.
102   * @return {@code true} if the token is already expired, {@code false} if not.
103   * @throws GeneralSecurityException if there is an error determining the
104   *         token's expiration date
105   */
106   boolean isTokenExpired(final OAuthToken token)
107              throws GeneralSecurityException;
108
109
110
111  /**
112   * Determines whether the incoming token is authentic (i.e. that it came from
113   * a trusted authorization server and not an attacker). Implementers are
114   * encouraged to use signed tokens and use this method to verify the
115   * signature, but other methods such as symmetric key encryption (using a
116   * shared secret) can be used as well.
117   *
118   * @param token the OAuth 2.0 bearer token.
119   * @return {@code true} if the bearer token can be verified as authentic and
120   *         originating from a trusted source, {@code false} if not.
121   * @throws GeneralSecurityException if there is an error determining whether
122   *         the token is authentic
123   */
124  boolean isTokenAuthentic(final OAuthToken token)
125              throws GeneralSecurityException;
126
127
128
129  /**
130   * Determines whether the incoming token is targeted for this server. This
131   * allows the implementation to reject the token early in the validation
132   * process if it can see that the intended recipient was not this server.
133   *
134   * @param token the OAuth 2.0 bearer token.
135   * @return {@code true} if the bearer token identifies this server as the
136   *         intended recipient, {@code false} if not.
137   * @throws GeneralSecurityException if there is an error determining whether
138   *         the token is for this server
139   */
140  boolean isTokenForThisServer(final OAuthToken token)
141              throws GeneralSecurityException;
142
143
144
145  /**
146   * Determines whether the incoming token is valid for the given request. This
147   * method should verify that the token is legitimate and grants access to the
148   * requested resource specified in the {@link SCIMRequest}. This typically
149   * involves checking the token scope and any other attributes granted by the
150   * authorization grant. Implementations may need to call back to the
151   * authorization server to verify that the token is still valid and has not
152   * been revoked.
153   *
154   * @param token the OAuth 2.0 bearer token.
155   * @param scimRequest the {@link SCIMRequest} that we are validating.
156   * @return an {@link OAuthTokenStatus} object which indicates whether the
157   *         bearer token is valid and grants access to the target resource.
158   *         This must not be {@code null}.
159   * @throws GeneralSecurityException if there is an error determining whether
160   *         the token is valid
161   */
162  OAuthTokenStatus validateToken(final OAuthToken token,
163                                 final SCIMRequest scimRequest)
164              throws GeneralSecurityException;
165
166
167
168  /**
169   * Extracts the DN of the authorization entry (for which to apply access
170   * controls) from the incoming token.
171   * <p>
172   * This may require performing an LDAP search in order to find the DN that
173   * matches a certain attribute value contained in the token.
174   *
175   * @param token the OAuth 2.0 bearer token.
176   * @return the authorization DN to use. This must not return {@code null}.
177   * @throws GeneralSecurityException if there is an error determining the
178   *         authorization user DN
179   */
180  String getAuthzDN(final OAuthToken token) throws GeneralSecurityException;
181}