summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--samples/OAuthConsumer/SampleWcf2.aspx.cs3
-rw-r--r--samples/OAuthServiceProvider/Code/DatabaseNonceStore.cs3
-rw-r--r--samples/OAuthServiceProvider/OAuth2.ashx.cs5
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj2
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs11
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingStrings.resx3
-rw-r--r--src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs6
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs (renamed from src/DotNetOpenAuth/OAuth2/ChannelElements/WebServerVerificationCodeBindingElement.cs)8
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/OAuthWrapAuthorizationServerChannel.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs19
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponse.cs42
-rw-r--r--src/DotNetOpenAuth/OAuth2/UserAgentClient.cs30
16 files changed, 96 insertions, 46 deletions
diff --git a/samples/OAuthConsumer/SampleWcf2.aspx.cs b/samples/OAuthConsumer/SampleWcf2.aspx.cs
index 6b6ced2..a4f0f1c 100644
--- a/samples/OAuthConsumer/SampleWcf2.aspx.cs
+++ b/samples/OAuthConsumer/SampleWcf2.aspx.cs
@@ -31,7 +31,8 @@
}
}
- if (Authorization != null) {
+ // Refresh the access token if it expires and if its lifetime is too short to be of use.
+ if (Authorization != null && Authorization.AccessTokenExpirationUtc.HasValue) {
client.RefreshToken(Authorization, TimeSpan.FromMinutes(1));
}
}
diff --git a/samples/OAuthServiceProvider/Code/DatabaseNonceStore.cs b/samples/OAuthServiceProvider/Code/DatabaseNonceStore.cs
index 1f8f56e..f0c10d1 100644
--- a/samples/OAuthServiceProvider/Code/DatabaseNonceStore.cs
+++ b/samples/OAuthServiceProvider/Code/DatabaseNonceStore.cs
@@ -4,6 +4,7 @@
using System.Linq;
using System.Web;
using DotNetOpenAuth.Messaging.Bindings;
+ using System.Data.SqlClient;
/// <summary>
/// A database-persisted nonce store.
@@ -47,6 +48,8 @@
return true;
} catch (System.Data.Linq.DuplicateKeyException) {
return false;
+ } catch (SqlException) {
+ return false;
}
}
diff --git a/samples/OAuthServiceProvider/OAuth2.ashx.cs b/samples/OAuthServiceProvider/OAuth2.ashx.cs
index 259803a..62aa680 100644
--- a/samples/OAuthServiceProvider/OAuth2.ashx.cs
+++ b/samples/OAuthServiceProvider/OAuth2.ashx.cs
@@ -38,11 +38,6 @@
throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
}
- // This sample doesn't implement support for immediate mode.
- if (!request.IsUserInteractionAllowed) {
- Global.AuthorizationServer.RejectAuthorizationRequest(request);
- }
-
// Redirect the user to a page that requires the user to be logged in.
Global.PendingOAuth2Authorization = request;
context.Response.Redirect("~/Members/Authorize2.aspx");
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index 20749dd..2b2a069 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -324,7 +324,7 @@ http://opensource.org/licenses/ms-pl.html
<Compile Include="OAuth2\ChannelElements\DataBag.cs" />
<Compile Include="OAuth2\ChannelElements\TimestampEncoder.cs" />
<Compile Include="OAuth2\ChannelElements\AuthorizationCode.cs" />
- <Compile Include="OAuth2\ChannelElements\WebServerVerificationCodeBindingElement.cs" />
+ <Compile Include="OAuth2\ChannelElements\AuthorizationCodeBindingElement.cs" />
<Compile Include="OAuth2\ChannelElements\AuthServerAllFlowsBindingElement.cs" />
<Compile Include="OAuth2\IAccessTokenAnalyzer.cs" />
<Compile Include="OAuth2\IAuthorizationServer.cs" />
diff --git a/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs b/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
index 21fd53a..e34dc03 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:4.0.30426.0
+// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -133,6 +133,15 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Looks up a localized string similar to Unable to instantiate the message part encoder/decoder type {0}..
+ /// </summary>
+ internal static string EncoderInstantiationFailed {
+ get {
+ return ResourceManager.GetString("EncoderInstantiationFailed", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to Error while deserializing message {0}..
/// </summary>
internal static string ErrorDeserializingMessage {
diff --git a/src/DotNetOpenAuth/Messaging/MessagingStrings.resx b/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
index 3a265f1..d7d0b01 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
+++ b/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
@@ -309,4 +309,7 @@
<data name="RequiredMessagePartConstantIncorrect" xml:space="preserve">
<value>The following message parts had constant value requirements that were unsatisfied: {0}</value>
</data>
+ <data name="EncoderInstantiationFailed" xml:space="preserve">
+ <value>Unable to instantiate the message part encoder/decoder type {0}.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs
index 462bb3c..df6dc73 100644
--- a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs
+++ b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs
@@ -361,7 +361,11 @@ namespace DotNetOpenAuth.Messaging.Reflection {
IMessagePartEncoder encoder;
if (!encoders.TryGetValue(messagePartEncoder, out encoder)) {
- encoder = encoders[messagePartEncoder] = (IMessagePartEncoder)Activator.CreateInstance(messagePartEncoder);
+ try {
+ encoder = encoders[messagePartEncoder] = (IMessagePartEncoder)Activator.CreateInstance(messagePartEncoder);
+ } catch (MissingMethodException ex) {
+ throw ErrorUtilities.Wrap(ex, MessagingStrings.EncoderInstantiationFailed, messagePartEncoder.FullName);
+ }
}
return encoder;
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs
index 04f83ac..c4257aa 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCode.cs
@@ -60,7 +60,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
true,
true,
false,
- WebServerVerificationCodeBindingElement.MaximumMessageAge,
+ AuthorizationCodeBindingElement.MaximumMessageAge,
authorizationServer.VerificationCodeNonceStore);
}
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/WebServerVerificationCodeBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs
index 5eb35ba..869a48c 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/WebServerVerificationCodeBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthorizationCodeBindingElement.cs
@@ -15,13 +15,13 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// <summary>
/// A binding element for OAuth 2.0 authorization servers that create/verify
- /// issued verification codes as part of obtaining access/refresh tokens.
+ /// issued authorization codes as part of obtaining access/refresh tokens.
/// </summary>
- internal class WebServerVerificationCodeBindingElement : AuthServerBindingElementBase {
+ internal class AuthorizationCodeBindingElement : AuthServerBindingElementBase {
/// <summary>
- /// Initializes a new instance of the <see cref="WebServerVerificationCodeBindingElement"/> class.
+ /// Initializes a new instance of the <see cref="AuthorizationCodeBindingElement"/> class.
/// </summary>
- internal WebServerVerificationCodeBindingElement() {
+ internal AuthorizationCodeBindingElement() {
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs
index 491ace9..7ad6940 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/EndUserAuthorizationResponseTypeEncoder.cs
@@ -14,7 +14,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// <summary>
/// Initializes a new instance of the <see cref="EndUserAuthorizationResponseTypeEncoder"/> class.
/// </summary>
- internal EndUserAuthorizationResponseTypeEncoder() {
+ public EndUserAuthorizationResponseTypeEncoder() {
}
#region IMessagePartEncoder Members
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs
index 5414793..f39eecd 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/GrantTypeEncoder.cs
@@ -14,7 +14,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// <summary>
/// Initializes a new instance of the <see cref="GrantTypeEncoder"/> class.
/// </summary>
- internal GrantTypeEncoder() {
+ public GrantTypeEncoder() {
}
#region IMessagePartEncoder Members
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuthWrapAuthorizationServerChannel.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuthWrapAuthorizationServerChannel.cs
index 6547b8b..dd3d02c 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuthWrapAuthorizationServerChannel.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/OAuthWrapAuthorizationServerChannel.cs
@@ -160,7 +160,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
if (authorizationServer != null) {
bindingElements.Add(new AuthServerAllFlowsBindingElement());
- bindingElements.Add(new WebServerVerificationCodeBindingElement());
+ bindingElements.Add(new AuthorizationCodeBindingElement());
bindingElements.Add(new AccessRequestBindingElement());
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs
index cea7148..d898862 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenAuthorizationCodeRequest.cs
@@ -59,7 +59,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// <summary>
/// Gets or sets the verification code previously communicated to the Client
- /// in <see cref="WebServerSuccessResponse.VerificationCode"/>.
+ /// in <see cref="EndUserAuthorizationSuccessResponse.AuthorizationCode"/>.
/// </summary>
/// <value>The verification code received from the authorization server.</value>
[MessagePart(Protocol.code, IsRequired = true, AllowEmpty = false)]
@@ -73,22 +73,5 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// </value>
[MessagePart(Protocol.redirect_uri, IsRequired = true, AllowEmpty = false)]
internal Uri Callback { get; set; }
-
- /// <summary>
- /// Gets or sets the identifier by which this client is known to the Authorization Server.
- /// </summary>
- /// <value>The client identifier.</value>
- [MessagePart(Protocol.client_id, IsRequired = true, AllowEmpty = false)]
- public string ClientIdentifier { get; set; }
-
- /// <summary>
- /// Gets or sets the client secret.
- /// </summary>
- /// <value>The client secret.</value>
- /// <remarks>
- /// 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)]
- public string ClientSecret { get; set; }
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs
index 4ebd6b7..09866cd 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRequestBase.cs
@@ -44,7 +44,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
[MessagePart(Protocol.grant_type, IsRequired = true, AllowEmpty = false, Encoder = typeof(GrantTypeEncoder))]
internal abstract GrantType GrantType { get; }
- [MessagePart(Protocol.scope, IsRequired = true, AllowEmpty = true)]
+ [MessagePart(Protocol.scope, IsRequired = false, AllowEmpty = true)]
internal string Scope { get; set; }
/// <summary>
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponse.cs
index 8a90572..6d4ce40 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponse.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationSuccessResponse.cs
@@ -15,7 +15,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// to indicate that user authorization was granted, and to return the user
/// to the Client where they started their experience.
/// </summary>
- internal class EndUserAuthorizationSuccessResponse : MessageBase, IMessageWithClientState {
+ internal class EndUserAuthorizationSuccessResponse : MessageBase, IMessageWithClientState, ITokenCarryingRequest {
/// <summary>
/// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessResponse"/> class.
/// </summary>
@@ -39,7 +39,7 @@ namespace DotNetOpenAuth.OAuth2.Messages {
((IMessageWithClientState)this).ClientState = request.ClientState;
}
- [MessagePart(Protocol.code, AllowEmpty = false, IsRequired = false)]
+ [MessagePart(Protocol.code, AllowEmpty = false, IsRequired = true)] // TODO: this isn't required when the access_token part is present.
internal string AuthorizationCode { get; set; }
[MessagePart(Protocol.access_token, AllowEmpty = false, IsRequired = false)]
@@ -73,5 +73,43 @@ namespace DotNetOpenAuth.OAuth2.Messages {
/// Gets or sets the authorizing user's account name.
/// </summary>
internal string AuthorizingUsername { get; set; }
+
+ #region ITokenCarryingRequest Members
+
+ string ITokenCarryingRequest.CodeOrToken {
+ get { return this.AuthorizationCode; }
+ set { this.AuthorizationCode = value;}
+ }
+
+ CodeOrTokenType ITokenCarryingRequest.CodeOrTokenType {
+ get { return CodeOrTokenType.AuthorizationCode; }
+ }
+
+ IAuthorizationDescription ITokenCarryingRequest.AuthorizationDescription { get; set; }
+
+ #endregion
+
+ /// <summary>
+ /// Checks the message state for conformity to the protocol specification
+ /// and throws an exception if the message is invalid.
+ /// </summary>
+ /// <remarks>
+ /// <para>Some messages have required fields, or combinations of fields that must relate to each other
+ /// in specialized ways. After deserializing a message, this method checks the state of the
+ /// message to see if it conforms to the protocol.</para>
+ /// <para>Note that this property should <i>not</i> check signatures or perform any state checks
+ /// outside this scope of this particular message.</para>
+ /// </remarks>
+ /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception>
+ protected override void EnsureValidMessage()
+ {
+ base.EnsureValidMessage();
+
+ ErrorUtilities.VerifyProtocol(
+ !string.IsNullOrEmpty(this.AuthorizationCode) || !string.IsNullOrEmpty(this.AccessToken),
+ MessagingStrings.RequiredParametersMissing,
+ this.GetType().Name,
+ string.Join(", ", new string[] { Protocol.code,Protocol.access_token}));
+ }
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/UserAgentClient.cs b/src/DotNetOpenAuth/OAuth2/UserAgentClient.cs
index f68393b..7815858 100644
--- a/src/DotNetOpenAuth/OAuth2/UserAgentClient.cs
+++ b/src/DotNetOpenAuth/OAuth2/UserAgentClient.cs
@@ -68,11 +68,11 @@ namespace DotNetOpenAuth.OAuth2 {
/// <param name="actualRedirectUrl">The actual URL of the incoming HTTP request.</param>
/// <param name="authorization">The authorization.</param>
/// <returns>The granted authorization, or <c>null</c> if the incoming HTTP request did not contain an authorization server response or authorization was rejected.</returns>
- public IAuthorizationState ProcessUserAuthorization(Uri actualRedirectUrl, IAuthorizationState authorization = null) {
+ public IAuthorizationState ProcessUserAuthorization(Uri actualRedirectUrl, IAuthorizationState authorizationState = null) {
Contract.Requires<ArgumentNullException>(actualRedirectUrl != null, "actualRedirectUrl");
- if (authorization == null) {
- authorization = new AuthorizationState();
+ if (authorizationState == null) {
+ authorizationState = new AuthorizationState();
}
var carrier = new HttpRequestInfo("GET", actualRedirectUrl, actualRedirectUrl.PathAndQuery, new System.Net.WebHeaderCollection(), null);
@@ -84,15 +84,29 @@ namespace DotNetOpenAuth.OAuth2 {
EndUserAuthorizationSuccessResponse success;
EndUserAuthorizationFailedResponse failure;
if ((success = response as EndUserAuthorizationSuccessResponse) != null) {
- this.UpdateAuthorizationWithResponse(authorization, success);
+ var accessTokenRequest = new AccessTokenAuthorizationCodeRequest(this.AuthorizationServer) {
+ ClientIdentifier = this.ClientIdentifier,
+ ClientSecret = this.ClientSecret,
+ Callback = authorizationState.Callback,
+ AuthorizationCode = success.AuthorizationCode,
+ };
+ IProtocolMessage accessTokenResponse = this.Channel.Request(accessTokenRequest);
+ var accessTokenSuccess = accessTokenResponse as AccessTokenSuccessResponse;
+ var failedAccessTokenResponse = accessTokenResponse as AccessTokenFailedResponse;
+ if (accessTokenSuccess != null) {
+ this.UpdateAuthorizationWithResponse(authorizationState, accessTokenSuccess);
+ } else if (failedAccessTokenResponse != null) {
+ authorizationState.Delete();
+ return null;
+ } else {
+ ErrorUtilities.ThrowProtocol(MessagingStrings.UnexpectedMessageReceivedOfMany);
+ }
} else if ((failure = response as EndUserAuthorizationFailedResponse) != null) {
- authorization.Delete();
+ authorizationState.Delete();
return null;
- } else {
- ErrorUtilities.ThrowProtocol(MessagingStrings.UnexpectedMessageReceivedOfMany);
}
- return authorization;
+ return authorizationState;
}
}
}