summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2011-06-16 22:18:59 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2011-06-16 22:18:59 -0700
commit1f77a2b10ed11ac084d1def41b3c891178b0520b (patch)
tree32f4abaaf950a44e37b887227b8c55d837718213 /src
parent4ad66d2d6aaa6c82ed3606e1c7134aeb960b6890 (diff)
downloadDotNetOpenAuth-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')
-rw-r--r--src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs11
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs24
-rw-r--r--src/DotNetOpenAuth/OAuth2/IAuthorizationServer.cs55
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAccessTokenResponse.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessAuthCodeResponse.cs2
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.