diff options
Diffstat (limited to 'src')
9 files changed, 106 insertions, 10 deletions
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index d9573f9..be4e21b 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -360,6 +360,7 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OAuth2\AuthorizationState.cs" /> <Compile Include="OAuth2\ChannelElements\AccessRequestBindingElement.cs" /> <Compile Include="OAuth2\ChannelElements\AccessToken.cs" /> + <Compile Include="OAuth2\ChannelElements\AccessTokenBindingElement.cs" /> <Compile Include="OAuth2\ChannelElements\AuthorizationDataBag.cs" /> <Compile Include="OAuth2\ChannelElements\AuthServerBindingElementBase.cs" /> <Compile Include="OAuth2\ChannelElements\GrantTypeEncoder.cs" /> diff --git a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs index 69768bc..20c903b 100644 --- a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs +++ b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs @@ -201,6 +201,13 @@ namespace DotNetOpenAuth.OAuth2 { response.Scope.ResetContents(scopes); } + RSACryptoServiceProvider rsa; + TimeSpan lifetime; + this.AuthorizationServerServices.PrepareAccessToken(authorizationRequest, out rsa, out lifetime); + IDisposable disposableKey = rsa; + disposableKey.Dispose(); + response.Lifetime = lifetime; + return response; } diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs index 129a277..d1e8609 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessRequestBindingElement.cs @@ -66,19 +66,10 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { var responseWithOriginatingRequest = (IDirectResponseProtocolMessage)message; var request = (IAccessTokenRequest)responseWithOriginatingRequest.OriginatingRequest; - // TODO: consider moving this AccessToken construction to its own binding element. 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); diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessToken.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessToken.cs index 932db73..aa9a14d 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessToken.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessToken.cs @@ -11,6 +11,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; + using System.Collections.Generic; /// <summary> /// A short-lived token that accompanies HTTP requests to protected data to authorize the request. @@ -38,6 +39,23 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { } /// <summary> + /// Initializes a new instance of the <see cref="AccessToken"/> class. + /// </summary> + /// <param name="clientIdentifier">The client identifier.</param> + /// <param name="scopes">The scopes.</param> + /// <param name="username">The username of the account that authorized this token.</param> + /// <param name="lifetime">The lifetime for this access token.</param> + internal AccessToken(string clientIdentifier, IEnumerable<string> scopes, string username, TimeSpan? lifetime) { + Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(clientIdentifier)); + + this.ClientIdentifier = clientIdentifier; + this.Scope.ResetContents(scopes); + this.User = username; + this.Lifetime = lifetime; + this.UtcCreationDate = DateTime.UtcNow; + } + + /// <summary> /// Gets or sets the lifetime of the access token. /// </summary> /// <value>The lifetime.</value> diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessTokenBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessTokenBindingElement.cs new file mode 100644 index 0000000..bdebce1 --- /dev/null +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AccessTokenBindingElement.cs @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------- +// <copyright file="AccessTokenBindingElement.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuth2.ChannelElements { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth2.Messages; + using System.Security.Cryptography; + + /// <summary> + /// Serializes access tokens inside an outgoing message. + /// </summary> + internal class AccessTokenBindingElement : AuthServerBindingElementBase { + /// <summary> + /// Initializes a new instance of the <see cref="AccessTokenBindingElement"/> class. + /// </summary> + internal AccessTokenBindingElement() { + } + + /// <summary> + /// Gets the protection commonly offered (if any) by this binding element. + /// </summary> + /// <value>Always <c>MessageProtections.None</c></value> + /// <remarks> + /// This value is used to assist in sorting binding elements in the channel stack. + /// </remarks> + public override MessageProtections Protection { + get { return MessageProtections.None; } + } + + /// <summary> + /// Prepares a message for sending based on the rules of this channel binding element. + /// </summary> + /// <param name="message">The message to prepare for sending.</param> + /// <returns> + /// The protections (if any) that this binding element applied to the message. + /// Null if this binding element did not even apply to this binding element. + /// </returns> + public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) { + var response = message as EndUserAuthorizationSuccessAccessTokenResponse; + if (response != null) { + var directResponse = (IDirectResponseProtocolMessage)response; + var request = (IAccessTokenRequest)directResponse.OriginatingRequest; + IAuthorizationCarryingRequest tokenCarryingResponse = response; + tokenCarryingResponse.AuthorizationDescription = new AccessToken(request.ClientIdentifier, response.Scope, response.AuthorizingUsername, response.Lifetime); + + return MessageProtections.None; + } + + return null; + } + + /// <summary> + /// Performs any transformation on an incoming message that may be necessary and/or + /// validates an incoming message based on the rules of this channel binding element. + /// </summary> + /// <param name="message">The incoming message to process.</param> + /// <returns> + /// The protections (if any) that this binding element applied to the message. + /// Null if this binding element did not even apply to this binding element. + /// </returns> + /// <exception cref="ProtocolException"> + /// Thrown when the binding element rules indicate that this message is invalid and should + /// NOT be processed. + /// </exception> + public override MessageProtections? ProcessIncomingMessage(IProtocolMessage message) { + return null; + } + } +} diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs index 237b1cd..03732bb 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs @@ -43,6 +43,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { this.CallbackHash = CalculateCallbackHash(callback); this.Scope.ResetContents(scopes); this.User = username; + this.UtcCreationDate = DateTime.UtcNow; } /// <summary> diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs index 31322a0..17b8c8c 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs @@ -60,7 +60,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { var directResponse = (IDirectResponseProtocolMessage)response; var request = (EndUserAuthorizationRequest)directResponse.OriginatingRequest; IAuthorizationCarryingRequest tokenCarryingResponse = response; - tokenCarryingResponse.AuthorizationDescription = new AuthorizationCode(request.ClientIdentifier, request.Callback, request.Scope, response.AuthorizingUsername); + tokenCarryingResponse.AuthorizationDescription = new AuthorizationCode(request.ClientIdentifier, request.Callback, response.Scope, response.AuthorizingUsername); return MessageProtections.None; } diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs index 0e648d4..888830e 100644 --- a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs +++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs @@ -99,6 +99,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { bindingElements.Add(new AuthServerAllFlowsBindingElement()); bindingElements.Add(new AuthorizationCodeBindingElement()); + bindingElements.Add(new AccessTokenBindingElement()); bindingElements.Add(new AccessRequestBindingElement()); return bindingElements.ToArray(); diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponseBase.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponseBase.cs index 9b308c8..c3d36fc 100644 --- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponseBase.cs +++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponseBase.cs @@ -42,6 +42,7 @@ namespace DotNetOpenAuth.OAuth2.Messages { Contract.Requires<ArgumentNullException>(request != null); ((IMessageWithClientState)this).ClientState = request.ClientState; this.Scope = new HashSet<string>(OAuthUtilities.ScopeStringComparer); + this.Scope.ResetContents(request.Scope); } /// <summary> |