summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2010-05-31 23:11:30 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2010-05-31 23:11:30 -0700
commitf00c9430bb49d0dcd54005c852fd2b7d7de2ce7e (patch)
treed92e72ff24191c3315078b438ea6204af9ab17dc
parent7f625de00c6daafd1c8e21b27b4b2dce8ce224b0 (diff)
downloadDotNetOpenAuth-f00c9430bb49d0dcd54005c852fd2b7d7de2ce7e.zip
DotNetOpenAuth-f00c9430bb49d0dcd54005c852fd2b7d7de2ce7e.tar.gz
DotNetOpenAuth-f00c9430bb49d0dcd54005c852fd2b7d7de2ce7e.tar.bz2
Lots of refactoring as we gather the token handling into centralized code.
-rw-r--r--samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs6
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj2
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessRequestBindingElement.cs84
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthServerWebServerFlowBindingElement.cs1
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/ChannelElements/IAccessTokenRequest.cs24
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs4
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/ChannelElements/RefreshAccessTokenBindingElement.cs46
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs15
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/IAuthorizationServer.cs30
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/Messages/AccessProtectedResourceRequest.cs13
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenRequest.cs15
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppAccessTokenRequest.cs15
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppSuccessResponse.cs14
-rw-r--r--src/DotNetOpenAuth/OAuthWrap/Protocol.cs5
14 files changed, 202 insertions, 72 deletions
diff --git a/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs
index 70474f2..6a36a83 100644
--- a/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs
+++ b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs
@@ -8,6 +8,7 @@
using DotNetOpenAuth.Messaging.Bindings;
using DotNetOpenAuth.OAuth.ChannelElements;
using DotNetOpenAuth.OAuthWrap;
+ using DotNetOpenAuth.OAuthWrap.ChannelElements;
internal class OAuth2AuthorizationServer : IAuthorizationServer {
private static readonly byte[] secret;
@@ -42,5 +43,10 @@
}
#endregion
+
+ public bool IsAuthorizationValid(IAuthorizationDescription authorization) {
+ // We don't support revoking tokens yet.
+ return true;
+ }
}
} \ No newline at end of file
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index 5131b7e..f4a02d4 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -309,6 +309,7 @@ http://opensource.org/licenses/ms-pl.html
<Compile Include="Messaging\StandardMessageFactory.cs" />
<Compile Include="OAuthWrap\AuthorizationServerBase.cs" />
<Compile Include="OAuthWrap\AuthorizationState.cs" />
+ <Compile Include="OAuthWrap\ChannelElements\AccessRequestBindingElement.cs" />
<Compile Include="OAuthWrap\ChannelElements\AccessToken.cs" />
<Compile Include="OAuthWrap\ChannelElements\AuthorizationDataBag.cs" />
<Compile Include="OAuthWrap\ChannelElements\AuthServerBindingElementBase.cs" />
@@ -316,7 +317,6 @@ http://opensource.org/licenses/ms-pl.html
<Compile Include="OAuthWrap\ChannelElements\IAuthorizationDescription.cs" />
<Compile Include="OAuthWrap\ChannelElements\OAuthWrapResourceServerChannel.cs" />
<Compile Include="Messaging\StandardMessageFactoryChannel.cs" />
- <Compile Include="OAuthWrap\ChannelElements\RefreshAccessTokenBindingElement.cs" />
<Compile Include="OAuthWrap\ChannelElements\RefreshToken.cs" />
<Compile Include="OAuthWrap\ChannelElements\DataBag.cs" />
<Compile Include="OAuthWrap\ChannelElements\TimestampEncoder.cs" />
diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessRequestBindingElement.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessRequestBindingElement.cs
new file mode 100644
index 0000000..9aa210f
--- /dev/null
+++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessRequestBindingElement.cs
@@ -0,0 +1,84 @@
+namespace DotNetOpenAuth.OAuthWrap.ChannelElements {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+
+ /// <summary>
+ /// Decodes verification codes, refresh tokens and access tokens on incoming messages.
+ /// </summary>
+ /// <remarks>
+ /// This binding element also ensures that the code/token coming in is issued to
+ /// the same client that is sending the code/token and that the authorization has
+ /// not been revoked and that an access token has not expired.
+ /// </remarks>
+ internal class AccessRequestBindingElement : AuthServerBindingElementBase {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AccessRequestBindingElement"/> class.
+ /// </summary>
+ internal AccessRequestBindingElement() {
+ }
+
+ public override MessageProtections Protection {
+ get { return MessageProtections.None; }
+ }
+
+ protected TimeSpan AccessTokenLifetime {
+ get { return TimeSpan.FromHours(1); }
+ }
+
+ public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
+ var tokenRequest = message as ITokenCarryingRequest;
+ if (tokenRequest != null) {
+ var tokenBag = (AuthorizationDataBag)tokenRequest.AuthorizationDescription;
+ tokenRequest.CodeOrToken = tokenBag.Encode();
+
+ return MessageProtections.None;
+ }
+
+ return null;
+ }
+
+ public override MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
+ var tokenRequest = message as ITokenCarryingRequest;
+ if (tokenRequest != null) {
+ try {
+ switch (tokenRequest.CodeOrTokenType) {
+ case CodeOrTokenType.VerificationCode:
+ tokenRequest.AuthorizationDescription = VerificationCode.Decode(this.OAuthChannel, tokenRequest.CodeOrToken, message);
+ break;
+ case CodeOrTokenType.RefreshToken:
+ tokenRequest.AuthorizationDescription = RefreshToken.Decode(this.OAuthChannel, tokenRequest.CodeOrToken, message);
+ break;
+ case CodeOrTokenType.AccessToken:
+ tokenRequest.AuthorizationDescription = AccessToken.Decode(this.OAuthChannel, tokenRequest.CodeOrToken, this.AccessTokenLifetime, message);
+ break;
+ default:
+ throw ErrorUtilities.ThrowInternal("Unexpected value for CodeOrTokenType: " + tokenRequest.CodeOrTokenType);
+ }
+ } catch (ExpiredMessageException ex) {
+ throw ErrorUtilities.Wrap(ex, Protocol.authorization_expired);
+ }
+
+ var accessRequest = message as IAccessTokenRequest;
+ if (accessRequest != null) {
+ // Make sure the client sending us this token is the client we issued the token to.
+ ErrorUtilities.VerifyProtocol(string.Equals(accessRequest.ClientIdentifier, accessRequest.AuthorizationDescription.ClientIdentifier, StringComparison.Ordinal), Protocol.incorrect_client_credentials);
+
+ // Check that the client secret is correct.
+ var client = this.AuthorizationServer.GetClientOrThrow(accessRequest.ClientIdentifier);
+ ErrorUtilities.VerifyProtocol(string.Equals(client.Secret, accessRequest.ClientSecret, StringComparison.Ordinal), Protocol.incorrect_client_credentials);
+ }
+
+ // Make sure the authorization this token represents hasn't already been revoked.
+ ErrorUtilities.VerifyProtocol(this.AuthorizationServer.IsAuthorizationValid(tokenRequest.AuthorizationDescription), Protocol.authorization_expired);
+
+ return MessageProtections.None;
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthServerWebServerFlowBindingElement.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthServerWebServerFlowBindingElement.cs
index 2f7b49e..5974414 100644
--- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthServerWebServerFlowBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthServerWebServerFlowBindingElement.cs
@@ -69,6 +69,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements {
var client = this.AuthorizationServer.GetClientOrThrow(authorizationRequest.ClientIdentifier);
ErrorUtilities.VerifyProtocol(client.Callback == null || client.Callback == authorizationRequest.Callback, OAuthWrapStrings.CallbackMismatch, client.Callback, authorizationRequest.Callback);
}
+
return null;
}
}
diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/IAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/IAccessTokenRequest.cs
index 3579955..426a87f 100644
--- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/IAccessTokenRequest.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/IAccessTokenRequest.cs
@@ -12,11 +12,27 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements {
using Messages;
using Messaging;
- internal interface IAccessTokenRequest : IDirectedProtocolMessage {
+ internal interface ITokenCarryingRequest : IDirectedProtocolMessage {
+ string CodeOrToken { get; set; }
+
+ CodeOrTokenType CodeOrTokenType { get; }
+
+ IAuthorizationDescription AuthorizationDescription { get; set; }
+ }
+
+ internal interface IAccessTokenRequest : ITokenCarryingRequest {
string ClientIdentifier { get; }
-
- string Scope { get; }
- string SecretType { get; set; }
+ string ClientSecret { get; }
+
+ string SecretType { get; }
+ }
+
+ internal enum CodeOrTokenType {
+ VerificationCode,
+
+ RefreshToken,
+
+ AccessToken,
}
}
diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs
index 0148b7a..3670ad9 100644
--- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs
@@ -70,7 +70,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements {
Contract.Requires<ArgumentNullException>(request != null, "request");
var response = new AccessTokenSuccessResponse(request) {
- Scope = request.Scope,
+ Scope = request.AuthorizationDescription.Scope,
Lifetime = TimeSpan.FromDays(1), // reasonable default for access token lifetime
// TODO: code here to initialize the response
AccessToken = "TODO",
@@ -178,7 +178,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements {
if (authorizationServer != null) {
bindingElements.Add(new AuthServerWebServerFlowBindingElement());
bindingElements.Add(new WebAppVerificationCodeBindingElement());
- bindingElements.Add(new RefreshAccessTokenBindingElement());
+ bindingElements.Add(new AccessRequestBindingElement());
}
return bindingElements.ToArray();
diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/RefreshAccessTokenBindingElement.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/RefreshAccessTokenBindingElement.cs
deleted file mode 100644
index 24aa1af..0000000
--- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/RefreshAccessTokenBindingElement.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="RefreshAccessTokenBindingElement.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuthWrap.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuthWrap.Messages;
-
- internal class RefreshAccessTokenBindingElement : AuthServerBindingElementBase {
- /// <summary>
- /// Gets the protection commonly offered (if any) by this binding element.
- /// </summary>
- /// <remarks>
- /// This value is used to assist in sorting binding elements in the channel stack.
- /// </remarks>
- public override MessageProtections Protection {
- get { return MessageProtections.None; }
- }
-
- public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
- return null;
- }
-
- public override MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
- var request = message as RefreshAccessTokenRequest;
- if (request != null) {
- // Decode and validate the refresh token
- var refreshToken = RefreshToken.Decode(this.OAuthChannel, request.RefreshToken, message);
-
- // Fill in the authorized access scope from the refresh token and fill in the property
- // on the message so that others can read it later.
- request.Scope = refreshToken.Scope;
-
- return MessageProtections.None;
- }
-
- return null;
- }
- }
-}
diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs
index faf896a..679ffd1 100644
--- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs
@@ -52,9 +52,8 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements {
if (response != null) {
var directResponse = (IDirectResponseProtocolMessage)response;
var request = (WebAppRequest)directResponse.OriginatingRequest;
-
- var code = new VerificationCode(this.OAuthChannel, request.ClientIdentifier, request.Callback, request.Scope, response.AuthorizingUsername);
- response.VerificationCode = code.Encode();
+ ITokenCarryingRequest tokenCarryingResponse = response;
+ tokenCarryingResponse.AuthorizationDescription = new VerificationCode(this.OAuthChannel, request.ClientIdentifier, request.Callback, request.Scope, response.AuthorizingUsername);
return MessageProtections.None;
}
@@ -82,14 +81,8 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements {
public override MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
var request = message as WebAppAccessTokenRequest;
if (request != null) {
- var client = this.AuthorizationServer.GetClient(request.ClientIdentifier);
- ErrorUtilities.VerifyProtocol(string.Equals(client.Secret, request.ClientSecret, StringComparison.Ordinal), Protocol.incorrect_client_credentials);
-
- var verificationCode = VerificationCode.Decode(this.OAuthChannel, request.VerificationCode, message);
- ErrorUtilities.VerifyProtocol(string.Equals(verificationCode.ClientIdentifier, request.ClientIdentifier, StringComparison.Ordinal), Protocol.bad_verification_code);
- verificationCode.VerifyCallback(request.Callback);
-
- request.Scope = verificationCode.Scope;
+ IAccessTokenRequest accessRequest = request;
+ ((VerificationCode)accessRequest.AuthorizationDescription).VerifyCallback(request.Callback);
return MessageProtections.None;
}
diff --git a/src/DotNetOpenAuth/OAuthWrap/IAuthorizationServer.cs b/src/DotNetOpenAuth/OAuthWrap/IAuthorizationServer.cs
index fccf067..8d5bea4 100644
--- a/src/DotNetOpenAuth/OAuthWrap/IAuthorizationServer.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/IAuthorizationServer.cs
@@ -13,6 +13,7 @@ namespace DotNetOpenAuth.OAuthWrap {
using System.Linq;
using System.Text;
using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuthWrap.ChannelElements;
[ContractClass(typeof(IAuthorizationServerContract))]
public interface IAuthorizationServer {
@@ -24,6 +25,30 @@ namespace DotNetOpenAuth.OAuthWrap {
/// <exception cref="ArgumentException">Thrown when no client with the given identifier is registered with this authorization server.</exception>
IConsumerDescription GetClient(string clientIdentifier);
+ /// <summary>
+ /// Determines whether a described authorization is (still) valid.
+ /// </summary>
+ /// <param name="authorization">The authorization.</param>
+ /// <returns>
+ /// <c>true</c> if the original authorization is still valid; otherwise, <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// <para>When establishing that an authorization is still valid,
+ /// it's very important to only match on recorded authorizations that
+ /// meet these criteria:</para>
+ /// 1) The client identifier matches.
+ /// 2) The user account matches.
+ /// 3) The scope on the recorded authorization must include all scopes in the given authorization.
+ /// 4) The date the recorded authorization was issued must be <em>no later</em> that the date the given authorization was issued.
+ /// <para>One possible scenario is where the user authorized a client, later revoked authorization,
+ /// and even later reinstated authorization. This subsequent recorded authorization
+ /// would not satisfy requirement #4 in the above list. This is important because the revocation
+ /// the user went through should invalidate all previously issued tokens as a matter of
+ /// security in the event the user was revoking access in order to sever authorization on a stolen
+ /// account or piece of hardware in which the tokens were stored. </para>
+ /// </remarks>
+ bool IsAuthorizationValid(IAuthorizationDescription authorization);
+
byte[] Secret { get; }
INonceStore VerificationCodeNonceStore { get; }
@@ -53,6 +78,11 @@ namespace DotNetOpenAuth.OAuthWrap {
throw new NotImplementedException();
}
}
+
+ bool IAuthorizationServer.IsAuthorizationValid(IAuthorizationDescription authorization) {
+ Contract.Requires<ArgumentNullException>(authorization != null, "authorization");
+ throw new NotImplementedException();
+ }
}
}
diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessProtectedResourceRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/AccessProtectedResourceRequest.cs
index 7b5569a..1f2efaa 100644
--- a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessProtectedResourceRequest.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/Messages/AccessProtectedResourceRequest.cs
@@ -12,7 +12,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
using ChannelElements;
using Messaging;
- internal class AccessProtectedResourceRequest : MessageBase {
+ internal class AccessProtectedResourceRequest : MessageBase, ITokenCarryingRequest {
/// <summary>
/// Initializes a new instance of the <see cref="AccessProtectedResourceRequest"/> class.
/// </summary>
@@ -22,6 +22,17 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
: base(version, MessageTransport.Direct, recipient) {
}
+ CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ get { return CodeOrTokenType.AccessToken; }
+ }
+
+ string ITokenCarryingRequest.CodeOrToken {
+ get { return this.AccessToken; }
+ set { this.AccessToken = value; }
+ }
+
+ IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+
[MessagePart("token", IsRequired = true, AllowEmpty = false)]
internal string AccessToken { get; set; }
diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenRequest.cs
index 8ab77ff..9b322f5 100644
--- a/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenRequest.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenRequest.cs
@@ -30,6 +30,17 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
: base(version, MessageTransport.Direct, tokenEndpoint) {
}
+ CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ get { return CodeOrTokenType.RefreshToken; }
+ }
+
+ string ITokenCarryingRequest.CodeOrToken {
+ get { return this.RefreshToken; }
+ set { this.RefreshToken = value; }
+ }
+
+ IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+
/// <summary>
/// Gets or sets the type of the secret.
/// </summary>
@@ -47,8 +58,6 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
[MessagePart(Protocol.client_id, IsRequired = true, AllowEmpty = false)]
public string ClientIdentifier { get; set; }
- public string Scope { get; set; }
-
/// <summary>
/// Gets or sets the client secret.
/// </summary>
@@ -57,7 +66,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
/// REQUIRED if the client identifier has a matching secret. The client secret as described in Section 3.4 (Client Credentials).
/// </remarks>
[MessagePart(Protocol.client_secret, IsRequired = false, AllowEmpty = true)]
- internal string ClientSecret { get; set; }
+ public string ClientSecret { get; set; }
/// <summary>
/// Gets or sets the refresh token.
diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppAccessTokenRequest.cs
index ff81f14..78cd5e0 100644
--- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppAccessTokenRequest.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppAccessTokenRequest.cs
@@ -50,6 +50,17 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
this.Format = ResponseFormat.Form;
}
+ CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ get { return CodeOrTokenType.VerificationCode; }
+ }
+
+ string ITokenCarryingRequest.CodeOrToken {
+ get { return this.VerificationCode; }
+ set { this.VerificationCode = value; }
+ }
+
+ IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+
/// <summary>
/// Gets or sets the identifier by which this client is known to the Authorization Server.
/// </summary>
@@ -65,7 +76,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
/// REQUIRED if the client identifier has a matching secret. The client secret as described in Section 3.4 (Client Credentials).
/// </remarks>
[MessagePart(Protocol.client_secret, IsRequired = false, AllowEmpty = true)]
- internal string ClientSecret { get; set; }
+ public string ClientSecret { get; set; }
/// <summary>
/// Gets or sets the verification code previously communicated to the Client
@@ -94,8 +105,6 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
[MessagePart(Protocol.secret_type, IsRequired = false, AllowEmpty = false)]
public string SecretType { get; set; }
- public string Scope { get; internal set; }
-
ResponseFormat IOAuthDirectResponseFormat.Format {
get { return this.Format.HasValue ? this.Format.Value : ResponseFormat.Json; }
}
diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppSuccessResponse.cs
index 2cfb017..277653e 100644
--- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppSuccessResponse.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebServer/WebAppSuccessResponse.cs
@@ -8,13 +8,14 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
using System;
using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuthWrap.ChannelElements;
/// <summary>
/// The message sent by the Authorization Server to the Client via the user agent
/// to indicate that user authorization was granted, and to return the user
/// to the Client where they started their experience.
/// </summary>
- internal class WebAppSuccessResponse : MessageBase, IMessageWithClientState {
+ internal class WebAppSuccessResponse : MessageBase, IMessageWithClientState, ITokenCarryingRequest {
/// <summary>
/// Initializes a new instance of the <see cref="WebAppSuccessResponse"/> class.
/// </summary>
@@ -38,6 +39,17 @@ namespace DotNetOpenAuth.OAuthWrap.Messages {
((IMessageWithClientState)this).ClientState = ((IMessageWithClientState)request).ClientState;
}
+ string ITokenCarryingRequest.CodeOrToken {
+ get { return this.VerificationCode; }
+ set { this.VerificationCode = value; }
+ }
+
+ CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ get { return CodeOrTokenType.VerificationCode; }
+ }
+
+ IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+
/// <summary>
/// Gets or sets some state as provided by the client in the authorization request.
/// </summary>
diff --git a/src/DotNetOpenAuth/OAuthWrap/Protocol.cs b/src/DotNetOpenAuth/OAuthWrap/Protocol.cs
index 4d71ef7..08329b9 100644
--- a/src/DotNetOpenAuth/OAuthWrap/Protocol.cs
+++ b/src/DotNetOpenAuth/OAuthWrap/Protocol.cs
@@ -59,6 +59,11 @@ namespace DotNetOpenAuth.OAuthWrap {
internal const string incorrect_client_credentials = "incorrect_client_credentials";
/// <summary>
+ /// The "authorization_expired" string.
+ /// </summary>
+ internal const string authorization_expired = "authorization_expired";
+
+ /// <summary>
/// The "redirect_uri" string.
/// </summary>
internal const string redirect_uri = "redirect_uri";