diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2011-06-16 22:18:59 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2011-06-16 22:18:59 -0700 |
commit | 1f77a2b10ed11ac084d1def41b3c891178b0520b (patch) | |
tree | 32f4abaaf950a44e37b887227b8c55d837718213 /src | |
parent | 4ad66d2d6aaa6c82ed3606e1c7134aeb960b6890 (diff) | |
download | DotNetOpenAuth-1f77a2b10ed11ac084d1def41b3c891178b0520b.zip DotNetOpenAuth-1f77a2b10ed11ac084d1def41b3c891178b0520b.tar.gz DotNetOpenAuth-1f77a2b10ed11ac084d1def41b3c891178b0520b.tar.bz2 |
Access token lifetimes are now controlled by the IAuthorizationServer instance supplied by the host.
It is consistent whether the access token is obtained via implicit grant or from a refresh token.
Diffstat (limited to 'src')
5 files changed, 65 insertions, 29 deletions
diff --git a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs index 0f57939..69768bc 100644 --- a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs +++ b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs @@ -208,14 +208,16 @@ namespace DotNetOpenAuth.OAuth2 { /// Prepares the response to an access token request. /// </summary> /// <param name="request">The request for an access token.</param> - /// <param name="accessTokenLifetime">The access token's lifetime.</param> /// <param name="includeRefreshToken">If set to <c>true</c>, the response will include a long-lived refresh token.</param> /// <returns>The response message to send to the client.</returns> - public virtual IDirectResponseProtocolMessage PrepareAccessTokenResponse(AccessTokenRequestBase request, TimeSpan? accessTokenLifetime = null, bool includeRefreshToken = true) { + public virtual IDirectResponseProtocolMessage PrepareAccessTokenResponse(AccessTokenRequestBase request, bool includeRefreshToken = true) { Contract.Requires<ArgumentNullException>(request != null); var tokenRequest = (IAuthorizationCarryingRequest)request; - using (var resourceServerEncryptionKey = this.AuthorizationServerServices.CreateAccessTokenEncryptionKey(request)) { + RSACryptoServiceProvider resourceServerEncryptionKey; + TimeSpan accessTokenLifetime; + this.AuthorizationServerServices.PrepareAccessToken(request, out resourceServerEncryptionKey, out accessTokenLifetime); + try { var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServerServices.AccessTokenSigningKey, resourceServerEncryptionKey); var accessToken = new AccessToken(tokenRequest.AuthorizationDescription, accessTokenLifetime); @@ -232,6 +234,9 @@ namespace DotNetOpenAuth.OAuth2 { } return response; + } finally { + IDisposable disposableKey = resourceServerEncryptionKey; + disposableKey.Dispose(); } } diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs index 9c9ebb4..129a277 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs @@ -13,6 +13,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OAuth2.Messages; + using System.Security.Cryptography; /// <summary> /// Decodes verification codes, refresh tokens and access tokens on incoming messages. @@ -66,18 +67,25 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { var request = (IAccessTokenRequest)responseWithOriginatingRequest.OriginatingRequest; // TODO: consider moving this AccessToken construction to its own binding element. - response.AuthorizationDescription = new AccessToken { - ClientIdentifier = request.ClientIdentifier, - UtcCreationDate = DateTime.UtcNow, - User = ((EndUserAuthorizationSuccessResponseBase)response).AuthorizingUsername, - }; - response.AuthorizationDescription.Scope.ResetContents(request.Scope); - - using (var resourceServerKey = this.AuthorizationServer.CreateAccessTokenEncryptionKey(request)) { + RSACryptoServiceProvider resourceServerKey; + TimeSpan lifetime; + this.AuthorizationServer.PrepareAccessToken(request, out resourceServerKey, out lifetime); + try { + response.AuthorizationDescription = new AccessToken { + ClientIdentifier = request.ClientIdentifier, + UtcCreationDate = DateTime.UtcNow, + User = ((EndUserAuthorizationSuccessResponseBase)response).AuthorizingUsername, + Lifetime = lifetime, + }; + response.AuthorizationDescription.Scope.ResetContents(request.Scope); + var tokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServer.AccessTokenSigningKey, resourceServerKey); var token = (AccessToken)response.AuthorizationDescription; response.CodeOrToken = tokenFormatter.Serialize(token); break; + } finally { + IDisposable disposableKey = resourceServerKey; + disposableKey.Dispose(); } default: throw ErrorUtilities.ThrowInternal(string.Format(CultureInfo.CurrentCulture, "Unexpected outgoing code or token type: {0}", response.CodeOrTokenType)); diff --git a/src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs index 6458433..457ce65 100644 --- a/src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs +++ b/src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs @@ -49,17 +49,28 @@ namespace DotNetOpenAuth.OAuth2 { RSACryptoServiceProvider AccessTokenSigningKey { get; } /// <summary> - /// Gets the crypto service provider with the asymmetric public key to use for encrypting access tokens for a specific resource server. + /// Obtains the encryption key and lifetime for an access token being created. /// </summary> - /// <param name="accessTokenRequestMessage">The access token request message.</param> - /// <returns> - /// A crypto service provider instance that contains the public key. - /// </returns> - /// <value>Must not be null.</value> + /// <param name="accessTokenRequestMessage"> + /// Details regarding the resources that the access token will grant access to, and the identity of the client + /// that will receive that access. + /// Based on this information the receiving resource server can be determined and the lifetime of the access + /// token can be set based on the sensitivity of the resources. + /// </param> + /// <param name="resourceServerEncryptionKey"> + /// Receives the crypto service provider with the asymmetric public key to use for encrypting access tokens for a specific resource server. + /// The caller is responsible to dispose of this value. + /// </param> + /// <param name="lifetime"> + /// Receives the lifetime for this access token. Note that within this lifetime, authorization <i>may</i> not be revokable. + /// Short lifetimes are recommended (i.e. one hour), particularly when the client is not authenticated or + /// the resources to which access is being granted are sensitive. + /// If <c>null</c>, a preconfigured default lifetime will be used. + /// </param> /// <remarks> /// The caller is responsible to dispose of the returned value. /// </remarks> - RSACryptoServiceProvider CreateAccessTokenEncryptionKey(IAccessTokenRequest accessTokenRequestMessage); + void PrepareAccessToken(IAccessTokenRequest accessTokenRequestMessage, out RSACryptoServiceProvider resourceServerEncryptionKey, out TimeSpan lifetime); /// <summary> /// Gets the client with a given identifier. @@ -142,18 +153,30 @@ namespace DotNetOpenAuth.OAuth2 { } /// <summary> - /// Gets the crypto service provider with the asymmetric private key to use for signing access tokens. + /// Obtains the encryption key and lifetime for an access token being created. /// </summary> - /// <returns> - /// A crypto service provider instance that contains the private key. - /// </returns> - /// <value>Must not be null, and must contain the private key.</value> + /// <param name="accessTokenRequestMessage"> + /// Details regarding the resources that the access token will grant access to, and the identity of the client + /// that will receive that access. + /// Based on this information the receiving resource server can be determined and the lifetime of the access + /// token can be set based on the sensitivity of the resources. + /// </param> + /// <param name="resourceServerEncryptionKey"> + /// Receives the crypto service provider with the asymmetric public key to use for encrypting access tokens for a specific resource server. + /// The caller is responsible to dispose of this value. + /// </param> + /// <param name="lifetime"> + /// Receives the lifetime for this access token. Note that within this lifetime, authorization <i>may</i> not be revokable. + /// Short lifetimes are recommended (i.e. one hour), particularly when the client is not authenticated or + /// the resources to which access is being granted are sensitive. + /// If <c>null</c>, a preconfigured default lifetime will be used. + /// </param> /// <remarks> - /// The public key in the private/public key pair will be used by the resource - /// servers to validate that the access token is minted by a trusted authorization server. + /// The caller is responsible to dispose of the returned value. /// </remarks> - RSACryptoServiceProvider IAuthorizationServer.CreateAccessTokenEncryptionKey(IAccessTokenRequest accessTokenRequestMessage) { - Contract.Ensures(Contract.Result<RSACryptoServiceProvider>() != null); + void IAuthorizationServer.PrepareAccessToken(IAccessTokenRequest accessTokenRequestMessage, out RSACryptoServiceProvider resourceServerEncryptionKey, out TimeSpan lifetime) { + Contract.Requires<ArgumentNullException>(accessTokenRequestMessage != null); + Contract.Ensures(Contract.ValueAtReturn<RSACryptoServiceProvider>(out resourceServerEncryptionKey) != null); throw new NotImplementedException(); } diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs index 4a3c534..a752a04 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs @@ -45,7 +45,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { this.TokenType = Protocol.AccessTokenTypes.Bearer; } - #region ITokenCarryingRequest Members + #region IAuthorizationCarryingRequest Members /// <summary> /// Gets or sets the verification code or refresh/access token. diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs index 37d4cc2..65965ef 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs @@ -40,7 +40,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { ((IMessageWithClientState)this).ClientState = request.ClientState; } - #region ITokenCarryingRequest Members + #region IAuthorizationCarryingRequest Members /// <summary> /// Gets or sets the verification code or refresh/access token. |