diff options
Diffstat (limited to 'src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2')
4 files changed, 86 insertions, 33 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs index ab20971..6a96c2d 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs @@ -143,30 +143,30 @@ namespace DotNetOpenAuth.OAuth2 { IProtocolMessage responseMessage; try { if (this.Channel.TryReadFromRequest(request, out requestMessage)) { + var accessTokenResult = this.AuthorizationServerServices.CreateAccessToken(requestMessage); + ErrorUtilities.VerifyHost(accessTokenResult != null, "IAuthorizationServerHost.CreateAccessToken must not return null."); + IAccessTokenRequestInternal accessRequestInternal = requestMessage; - accessRequestInternal.AccessTokenCreationParameters = this.AuthorizationServerServices.GetAccessTokenParameters(requestMessage); - ErrorUtilities.VerifyHost(accessRequestInternal.AccessTokenCreationParameters != null, "IAuthorizationServerHost.GetAccessTokenParameters must not return null."); + accessRequestInternal.AccessTokenResult = accessTokenResult; - var successResponseMessage = this.PrepareAccessTokenResponse(requestMessage, accessRequestInternal.AccessTokenCreationParameters.IncludeRefreshToken); - successResponseMessage.Lifetime = accessRequestInternal.AccessTokenCreationParameters.AccessTokenLifetime; + var successResponseMessage = this.PrepareAccessTokenResponse(requestMessage, accessTokenResult.AllowRefreshToken); + successResponseMessage.Lifetime = accessTokenResult.AccessToken.Lifetime; var authCarryingRequest = requestMessage as IAuthorizationCarryingRequest; if (authCarryingRequest != null) { + accessTokenResult.AccessToken.ApplyAuthorization(authCarryingRequest.AuthorizationDescription); IAccessTokenIssuingResponse accessTokenIssuingResponse = successResponseMessage; - accessTokenIssuingResponse.AuthorizationDescription = new AccessToken(authCarryingRequest.AuthorizationDescription, successResponseMessage.Lifetime); - accessTokenIssuingResponse.AuthorizationDescription.ExtraData.AddRange(accessRequestInternal.AccessTokenCreationParameters.ExtraClaims); + accessTokenIssuingResponse.AuthorizationDescription = accessTokenResult.AccessToken; } responseMessage = successResponseMessage; } else { - responseMessage = new AccessTokenFailedResponse() { Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest, }; + responseMessage = new AccessTokenFailedResponse() { Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest }; } } catch (TokenEndpointProtocolException ex) { responseMessage = ex.GetResponse(); } catch (ProtocolException) { - responseMessage = new AccessTokenFailedResponse() { - Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest, - }; + responseMessage = new AccessTokenFailedResponse() { Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest }; } return this.Channel.PrepareResponse(responseMessage); @@ -212,16 +212,17 @@ namespace DotNetOpenAuth.OAuth2 { switch (authorizationRequest.ResponseType) { case EndUserAuthorizationResponseType.AccessToken: IAccessTokenRequestInternal accessRequestInternal = (EndUserAuthorizationImplicitRequest)authorizationRequest; - accessRequestInternal.AccessTokenCreationParameters = this.AuthorizationServerServices.GetAccessTokenParameters(accessRequestInternal); + var accessTokenResult = this.AuthorizationServerServices.CreateAccessToken(accessRequestInternal); + ErrorUtilities.VerifyHost(accessTokenResult != null, "IAuthorizationServerHost.CreateAccessToken must not return null."); + + accessRequestInternal.AccessTokenResult = accessTokenResult; var implicitGrantResponse = new EndUserAuthorizationSuccessAccessTokenResponse(callback, authorizationRequest); - implicitGrantResponse.Lifetime = accessRequestInternal.AccessTokenCreationParameters.AccessTokenLifetime; + implicitGrantResponse.Lifetime = accessTokenResult.AccessToken.Lifetime; + accessTokenResult.AccessToken.ApplyAuthorization(implicitGrantResponse.Scope, userName, implicitGrantResponse.Lifetime); + IAccessTokenCarryingRequest tokenCarryingResponse = implicitGrantResponse; - tokenCarryingResponse.AuthorizationDescription = new AccessToken( - implicitGrantResponse.Scope, - userName, - implicitGrantResponse.Lifetime); - tokenCarryingResponse.AuthorizationDescription.ExtraData.AddRange(accessRequestInternal.AccessTokenCreationParameters.ExtraClaims); + tokenCarryingResponse.AuthorizationDescription = accessTokenResult.AccessToken; response = implicitGrantResponse; break; @@ -279,24 +280,24 @@ namespace DotNetOpenAuth.OAuth2 { /// Prepares the response to an access token request. /// </summary> /// <param name="request">The request for an access token.</param> - /// <param name="includeRefreshToken">If set to <c>true</c>, the response will include a long-lived refresh token.</param> + /// <param name="allowRefreshToken">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> - private AccessTokenSuccessResponse PrepareAccessTokenResponse(AccessTokenRequestBase request, bool includeRefreshToken = true) { + private AccessTokenSuccessResponse PrepareAccessTokenResponse(AccessTokenRequestBase request, bool allowRefreshToken = true) { Requires.NotNull(request, "request"); - if (includeRefreshToken) { + if (allowRefreshToken) { if (request is AccessTokenClientCredentialsRequest) { // Per OAuth 2.0 section 4.4.3 (draft 23), refresh tokens should never be included // in a response to an access token request that used the client credential grant type. Logger.OAuth.Debug("Suppressing refresh token in access token response because the grant type used by the client disallows it."); - includeRefreshToken = false; + allowRefreshToken = false; } } var tokenRequest = (IAuthorizationCarryingRequest)request; var accessTokenRequest = (IAccessTokenRequestInternal)request; var response = new AccessTokenSuccessResponse(request) { - HasRefreshToken = includeRefreshToken, + HasRefreshToken = allowRefreshToken, }; response.Scope.ResetContents(tokenRequest.AuthorizationDescription.Scope); return response; diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServerAccessToken.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServerAccessToken.cs new file mode 100644 index 0000000..c577a0a --- /dev/null +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServerAccessToken.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------- +// <copyright file="AuthorizationServerAccessToken.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuth2 { + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Linq; + using System.Security.Cryptography; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth2.ChannelElements; + + /// <summary> + /// An access token minted by the authorization server that can be serialized for transmission to the client. + /// </summary> + public class AuthorizationServerAccessToken : AccessToken { + /// <summary> + /// Initializes a new instance of the <see cref="AuthorizationServerAccessToken"/> class. + /// </summary> + public AuthorizationServerAccessToken() { + } + + /// <summary> + /// Gets or sets the crypto service provider with the asymmetric private key to use for signing access tokens. + /// </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> + /// <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. + /// </remarks> + public RSACryptoServiceProvider AccessTokenSigningKey { get; set; } + + /// <summary> + /// Gets or sets the key to encrypt the access token. + /// </summary> + public RSACryptoServiceProvider ResourceServerEncryptionKey { get; set; } + + /// <summary> + /// Serializes this instance to a simple string for transmission to the client. + /// </summary> + /// <returns>A non-empty string.</returns> + protected internal override string Serialize() { + var formatter = CreateFormatter(this.AccessTokenSigningKey, this.ResourceServerEncryptionKey); + return formatter.Serialize(this); + } + } +} diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs index 41bc609..494a10b 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs @@ -71,10 +71,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { var accessTokenResponse = message as IAccessTokenIssuingResponse; if (accessTokenResponse != null && accessTokenResponse.AuthorizationDescription != null) { ErrorUtilities.VerifyInternal(request != null, "We should always have a direct request message for this case."); - var accessTokenFormatter = AccessToken.CreateFormatter( - request.AccessTokenCreationParameters.AccessTokenSigningKey, - request.AccessTokenCreationParameters.ResourceServerEncryptionKey); - accessTokenResponse.AccessToken = accessTokenFormatter.Serialize(accessTokenResponse.AuthorizationDescription); + accessTokenResponse.AccessToken = accessTokenResponse.AuthorizationDescription.Serialize(); } return null; @@ -105,14 +102,16 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { var authCodeCarrier = message as IAuthorizationCodeCarryingRequest; if (authCodeCarrier != null) { var authorizationCodeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer); - var authorizationCode = authorizationCodeFormatter.Deserialize(message, authCodeCarrier.Code, Protocol.code); + var authorizationCode = new AuthorizationCode(); + authorizationCodeFormatter.Deserialize(authorizationCode, message, authCodeCarrier.Code, Protocol.code); authCodeCarrier.AuthorizationDescription = authorizationCode; } var refreshTokenCarrier = message as IRefreshTokenCarryingRequest; if (refreshTokenCarrier != null) { var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore); - var refreshToken = refreshTokenFormatter.Deserialize(message, refreshTokenCarrier.RefreshToken, Protocol.refresh_token); + var refreshToken = new RefreshToken(); + refreshTokenFormatter.Deserialize(refreshToken, message, refreshTokenCarrier.RefreshToken, Protocol.refresh_token); refreshTokenCarrier.AuthorizationDescription = refreshToken; } diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs index c31ec81..4c25c16 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/IAuthorizationServerHost.cs @@ -38,14 +38,15 @@ namespace DotNetOpenAuth.OAuth2 { INonceStore NonceStore { get; } /// <summary> - /// Obtains parameters to go into the formulation of an access token. + /// Acquires the access token and related parameters that go into the formulation of the token endpoint's response to a client. /// </summary> /// <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> + /// token can be set based on the sensitivity of the resources. + /// </param> /// <returns>A non-null parameters instance that DotNetOpenAuth will dispose after it has been used.</returns> - AccessTokenParameters GetAccessTokenParameters(IAccessTokenRequest accessTokenRequestMessage); + AccessTokenResult CreateAccessToken(IAccessTokenRequest accessTokenRequestMessage); /// <summary> /// Gets the client with a given identifier. @@ -205,9 +206,9 @@ namespace DotNetOpenAuth.OAuth2 { /// <returns> /// A non-null parameters instance that DotNetOpenAuth will dispose after it has been used. /// </returns> - AccessTokenParameters IAuthorizationServerHost.GetAccessTokenParameters(IAccessTokenRequest accessTokenRequestMessage) { + AccessTokenResult IAuthorizationServerHost.CreateAccessToken(IAccessTokenRequest accessTokenRequestMessage) { Contract.Requires(accessTokenRequestMessage != null); - Contract.Ensures(Contract.Result<AccessTokenParameters>() != null); + Contract.Ensures(Contract.Result<AccessTokenResult>() != null); throw new NotImplementedException(); } } |