diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2010-06-01 20:46:14 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2010-06-01 20:46:14 -0700 |
commit | 63ea38240513d1c72b83d9df1c5e313bacf0dd21 (patch) | |
tree | 5124975c59c3fa5663a49b914f84a519cff00af9 | |
parent | d4e5fc6be9c78a0b05fd833661d0595cee5bbc5f (diff) | |
download | DotNetOpenAuth-63ea38240513d1c72b83d9df1c5e313bacf0dd21.zip DotNetOpenAuth-63ea38240513d1c72b83d9df1c5e313bacf0dd21.tar.gz DotNetOpenAuth-63ea38240513d1c72b83d9df1c5e313bacf0dd21.tar.bz2 |
Replaced channel dependency on DataBag class with just the secret and its own message description collection.
8 files changed, 58 insertions, 49 deletions
diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessRequestBindingElement.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessRequestBindingElement.cs index ab7d999..d102ee6 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessRequestBindingElement.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessRequestBindingElement.cs @@ -43,13 +43,13 @@ try { switch (tokenRequest.CodeOrTokenType) { case CodeOrTokenType.VerificationCode: - tokenRequest.AuthorizationDescription = VerificationCode.Decode(this.OAuthChannel, tokenRequest.CodeOrToken, message); + tokenRequest.AuthorizationDescription = VerificationCode.Decode(this.AuthorizationServer.Secret, this.AuthorizationServer.VerificationCodeNonceStore, tokenRequest.CodeOrToken, message); break; case CodeOrTokenType.RefreshToken: - tokenRequest.AuthorizationDescription = RefreshToken.Decode(this.OAuthChannel, tokenRequest.CodeOrToken, message); + tokenRequest.AuthorizationDescription = RefreshToken.Decode(this.AuthorizationServer.Secret, tokenRequest.CodeOrToken, message); break; case CodeOrTokenType.AccessToken: - tokenRequest.AuthorizationDescription = AccessToken.Decode(this.OAuthChannel, tokenRequest.CodeOrToken, message); + tokenRequest.AuthorizationDescription = AccessToken.Decode(this.AuthorizationServer.Secret, tokenRequest.CodeOrToken, message); break; default: throw ErrorUtilities.ThrowInternal("Unexpected value for CodeOrTokenType: " + tokenRequest.CodeOrTokenType); diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessToken.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessToken.cs index beeb166..3d3ad44 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessToken.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AccessToken.cs @@ -18,14 +18,14 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { /// Initializes a new instance of the <see cref="AccessToken"/> class. /// </summary> /// <param name="channel">The channel.</param> - private AccessToken(OAuthWrapAuthorizationServerChannel channel) - : base(channel, true, true) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + private AccessToken(byte[] secret) + : base(secret, true, true) { + Contract.Requires<ArgumentNullException>(secret != null, "channel"); } - internal AccessToken(OAuthWrapAuthorizationServerChannel channel, IAuthorizationDescription authorization, TimeSpan? lifetime) - : this(channel) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + internal AccessToken(byte[] secret, IAuthorizationDescription authorization, TimeSpan? lifetime) + : this(secret) { + Contract.Requires<ArgumentNullException>(secret != null, "secret"); Contract.Requires<ArgumentNullException>(authorization != null, "authorization"); this.ClientIdentifier = authorization.ClientIdentifier; @@ -37,12 +37,12 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { internal TimeSpan? Lifetime { get; set; } - internal static AccessToken Decode(OAuthWrapAuthorizationServerChannel channel, string value, IProtocolMessage containingMessage = null) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + internal static AccessToken Decode(byte[] secret, string value, IProtocolMessage containingMessage = null) { + Contract.Requires<ArgumentNullException>(secret != null, "secret"); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value)); Contract.Ensures(Contract.Result<AccessToken>() != null); - var self = new AccessToken(channel); + var self = new AccessToken(secret); self.Decode(value, containingMessage); return self; } diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthorizationDataBag.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthorizationDataBag.cs index 6bd3041..0c14e51 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthorizationDataBag.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/AuthorizationDataBag.cs @@ -14,9 +14,8 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { using DotNetOpenAuth.Messaging.Bindings; internal abstract class AuthorizationDataBag : DataBag, IAuthorizationDescription { - protected AuthorizationDataBag(OAuthWrapAuthorizationServerChannel channel, bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) - : base(channel, signed, encrypted, compressed, maximumAge, decodeOnceOnly) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + protected AuthorizationDataBag(byte[] secret, bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) + : base(secret, signed, encrypted, compressed, maximumAge, decodeOnceOnly) { } [MessagePart] diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/DataBag.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/DataBag.cs index d398685..eb7e069 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/DataBag.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/DataBag.cs @@ -14,11 +14,16 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; + using DotNetOpenAuth.Messaging.Reflection; using DotNetOpenAuth.OAuthWrap.Messages; internal abstract class DataBag : MessageBase { + private static readonly MessageDescriptionCollection MessageDescriptions = new MessageDescriptionCollection(); + private const int NonceLength = 6; + private readonly byte[] secret; + private readonly bool signed; private readonly INonceStore decodeOnceOnly; @@ -29,15 +34,17 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { private readonly bool compressed; - protected DataBag(OAuthWrapAuthorizationServerChannel channel, bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) + protected DataBag(byte[] secret = null, bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) : base(Protocol.Default.Version) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); - Contract.Requires<ArgumentException>(channel.AuthorizationServer != null); + Contract.Requires<ArgumentException>(secret != null || (signed == null && encrypted == null), "A secret is required when signing or encrypting is required."); Contract.Requires<ArgumentException>(signed || decodeOnceOnly == null, "A signature must be applied if this data is meant to be decoded only once."); Contract.Requires<ArgumentException>(maximumAge.HasValue || decodeOnceOnly == null, "A maximum age must be given if a message can only be decoded once."); - this.Hasher = new HMACSHA256(channel.AuthorizationServer.Secret); - this.Channel = channel; + if (secret != null) { + this.Hasher = new HMACSHA256(secret); + } + + this.secret = secret; this.signed = signed; this.maximumAge = maximumAge; this.decodeOnceOnly = decodeOnceOnly; @@ -45,8 +52,6 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { this.compressed = compressed; } - protected OAuthWrapAuthorizationServerChannel Channel { get; set; } - protected HashAlgorithm Hasher { get; set; } [MessagePart("sig")] @@ -71,7 +76,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { this.Signature = this.CalculateSignature(); } - var fields = this.Channel.MessageDescriptions.GetAccessor(this); + var fields = MessageDescriptions.GetAccessor(this); string value = Uri.EscapeDataString(this.BagTypeName) + "&" + MessagingUtilities.CreateQueryString(fields); byte[] encoded = Encoding.UTF8.GetBytes(value); @@ -81,7 +86,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { } if (encrypted) { - encoded = MessagingUtilities.Encrypt(encoded, this.Channel.AuthorizationServer.Secret); + encoded = MessagingUtilities.Encrypt(encoded, this.secret); } return Convert.ToBase64String(encoded); @@ -93,7 +98,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { byte[] encoded = Convert.FromBase64String(value); if (encrypted) { - encoded = MessagingUtilities.Decrypt(encoded, this.Channel.AuthorizationServer.Secret); + encoded = MessagingUtilities.Decrypt(encoded, this.secret); } if (compressed) { @@ -103,7 +108,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { value = Encoding.UTF8.GetString(encoded); // Deserialize into this newly created instance. - var fields = this.Channel.MessageDescriptions.GetAccessor(this); + var fields = MessageDescriptions.GetAccessor(this); string[] halves = value.Split(new char[] { '&' }, 2); ErrorUtilities.VerifyProtocol(string.Equals(halves[0], Uri.EscapeDataString(this.BagTypeName), StringComparison.Ordinal), "Unexpected type of message while decoding."); value = halves[1]; @@ -146,8 +151,10 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { /// </summary> /// <returns>The calculated signature.</returns> private string CalculateSignature() { + Contract.Requires<InvalidOperationException>(this.Hasher != null); + // Sign the data, being sure to avoid any impact of the signature field itself. - var fields = this.Channel.MessageDescriptions.GetAccessor(this); + var fields = MessageDescriptions.GetAccessor(this); var fieldsCopy = fields.ToDictionary(); fieldsCopy.Remove("sig"); return this.Hasher.ComputeHash(fieldsCopy); diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs index 0d11e57..bcb6c05 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapAuthorizationServerChannel.cs @@ -69,7 +69,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { public virtual AccessTokenSuccessResponse PrepareAccessToken(IAccessTokenRequest request, TimeSpan? accessTokenLifetime = null, bool includeRefreshToken = true) { Contract.Requires<ArgumentNullException>(request != null, "request"); - var accessToken = new AccessToken(this, request.AuthorizationDescription, accessTokenLifetime); + var accessToken = new AccessToken(this.AuthorizationServer.Secret, request.AuthorizationDescription, accessTokenLifetime); var response = new AccessTokenSuccessResponse(request) { Scope = request.AuthorizationDescription.Scope, AccessToken = accessToken.Encode(), @@ -77,7 +77,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { }; if (includeRefreshToken) { - var refreshToken = new RefreshToken(this, request.AuthorizationDescription); + var refreshToken = new RefreshToken(this.AuthorizationServer.Secret, request.AuthorizationDescription); response.RefreshToken = refreshToken.Encode(); } diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/RefreshToken.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/RefreshToken.cs index 848ff48..d813453 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/RefreshToken.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/RefreshToken.cs @@ -17,14 +17,14 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { /// Initializes a new instance of the <see cref="RefreshToken"/> class. /// </summary> /// <param name="channel">The channel.</param> - private RefreshToken(OAuthWrapAuthorizationServerChannel channel) - : base(channel, true, true) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + private RefreshToken(byte[] secret) + : base(secret, true, true) { + Contract.Requires<ArgumentNullException>(secret != null, "secret"); } - internal RefreshToken(OAuthWrapAuthorizationServerChannel channel, IAuthorizationDescription authorization) - : this(channel) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + internal RefreshToken(byte[] secret, IAuthorizationDescription authorization) + : this(secret) { + Contract.Requires<ArgumentNullException>(secret != null, "secret"); Contract.Requires<ArgumentNullException>(authorization != null, "authorization"); this.ClientIdentifier = authorization.ClientIdentifier; @@ -33,12 +33,12 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { this.Scope = authorization.Scope; } - internal static RefreshToken Decode(OAuthWrapAuthorizationServerChannel channel, string value, IProtocolMessage containingMessage = null) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + internal static RefreshToken Decode(byte[] secret, string value, IProtocolMessage containingMessage = null) { + Contract.Requires<ArgumentNullException>(secret != null, "secret"); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value)); Contract.Ensures(Contract.Result<RefreshToken>() != null); - var self = new RefreshToken(channel); + var self = new RefreshToken(secret); self.Decode(value, containingMessage); return self; } diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/VerificationCode.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/VerificationCode.cs index 159e355..17f7948 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/VerificationCode.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/VerificationCode.cs @@ -18,10 +18,12 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { /// <param name="callback">The callback.</param> /// <param name="scope">The scope.</param> /// <param name="username">The username.</param> - internal VerificationCode(OAuthWrapAuthorizationServerChannel channel, string clientIdentifier, Uri callback, string scope, string username) - : this(channel) { + internal VerificationCode(byte[] secret, INonceStore nonceStore, string clientIdentifier, Uri callback, string scope, string username) + : this(secret, nonceStore) { + Contract.Requires<ArgumentNullException>(secret != null, "secret"); + Contract.Requires<ArgumentNullException>(nonceStore != null, "nonceStore"); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(clientIdentifier)); - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + Contract.Requires<ArgumentNullException>(secret != null, "secret"); Contract.Requires<ArgumentNullException>(callback != null, "callback"); this.ClientIdentifier = clientIdentifier; @@ -34,10 +36,10 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { /// Initializes a new instance of the <see cref="VerificationCode"/> class. /// </summary> /// <param name="channel">The channel.</param> - private VerificationCode(OAuthWrapAuthorizationServerChannel channel) - : base(channel, true, true, false, MaximumMessageAge, channel.AuthorizationServer.VerificationCodeNonceStore) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); - Contract.Requires<ArgumentException>(channel.AuthorizationServer != null); + private VerificationCode(byte[] secret, INonceStore nonceStore) + : base(secret, true, true, false, MaximumMessageAge, nonceStore) { + Contract.Requires<ArgumentNullException>(secret != null, "secret"); + Contract.Requires<ArgumentNullException>(nonceStore != null, "nonceStore"); } [MessagePart("cb")] @@ -50,13 +52,14 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { get { return StandardExpirationBindingElement.MaximumMessageAge; } } - internal static VerificationCode Decode(OAuthWrapAuthorizationServerChannel channel, string value, IProtocolMessage containingMessage) { - Contract.Requires<ArgumentNullException>(channel != null, "channel"); + internal static VerificationCode Decode(byte[] secret, INonceStore nonceStore, string value, IProtocolMessage containingMessage) { + Contract.Requires<ArgumentNullException>(secret != null, "secret"); + Contract.Requires<ArgumentNullException>(nonceStore != null, "nonceStore"); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value)); Contract.Requires<ArgumentNullException>(containingMessage != null, "containingMessage"); Contract.Ensures(Contract.Result<VerificationCode>() != null); - var self = new VerificationCode(channel); + var self = new VerificationCode(secret, nonceStore); self.Decode(value, containingMessage); return self; } diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs index 679ffd1..b81a9ad 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/WebAppVerificationCodeBindingElement.cs @@ -53,7 +53,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { var directResponse = (IDirectResponseProtocolMessage)response; var request = (WebAppRequest)directResponse.OriginatingRequest; ITokenCarryingRequest tokenCarryingResponse = response; - tokenCarryingResponse.AuthorizationDescription = new VerificationCode(this.OAuthChannel, request.ClientIdentifier, request.Callback, request.Scope, response.AuthorizingUsername); + tokenCarryingResponse.AuthorizationDescription = new VerificationCode(this.AuthorizationServer.Secret, this.AuthorizationServer.VerificationCodeNonceStore, request.ClientIdentifier, request.Callback, request.Scope, response.AuthorizingUsername); return MessageProtections.None; } |