summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2012-03-30 23:24:46 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2012-03-30 23:24:46 -0700
commiteb5a492c0cf6d60badf41ac20229c19e14adccfe (patch)
tree87cf1ef128629b296c76adb946353705d99f492a /src
parent12ff0dc0fa007968813675a2e0d447389a5c1bd3 (diff)
downloadDotNetOpenAuth-eb5a492c0cf6d60badf41ac20229c19e14adccfe.zip
DotNetOpenAuth-eb5a492c0cf6d60badf41ac20229c19e14adccfe.tar.gz
DotNetOpenAuth-eb5a492c0cf6d60badf41ac20229c19e14adccfe.tar.bz2
Consolidated all code and token serializations to one binding element.
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj2
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessRequestBindingElement.cs154
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessTokenBindingElement.cs18
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs56
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs120
6 files changed, 180 insertions, 172 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj
index cffffa9..9498295 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj
@@ -25,7 +25,7 @@
<DependentUpon>AuthServerStrings.resx</DependentUpon>
</Compile>
<Compile Include="OAuth2\AuthServerUtilities.cs" />
- <Compile Include="OAuth2\ChannelElements\AccessRequestBindingElement.cs" />
+ <Compile Include="OAuth2\ChannelElements\TokenCodeSerializationBindingElement.cs" />
<Compile Include="OAuth2\ChannelElements\AccessTokenBindingElement.cs" />
<Compile Include="OAuth2\ChannelElements\AuthorizationCode.cs" />
<Compile Include="OAuth2\ChannelElements\MessageValidationBindingElement.cs" />
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessRequestBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessRequestBindingElement.cs
deleted file mode 100644
index 1d85630..0000000
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessRequestBindingElement.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="AccessRequestBindingElement.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth2.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Globalization;
- using System.Linq;
- using System.Security.Cryptography;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Bindings;
- using DotNetOpenAuth.OAuth2.AuthServer.ChannelElements;
- using DotNetOpenAuth.OAuth2.Messages;
-
- /// <summary>
- /// Decodes authorization codes and refresh 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>
- /// Gets the protection commonly offered (if any) by this binding element.
- /// </summary>
- /// <value></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>
- /// <remarks>
- /// Implementations that provide message protection must honor the
- /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
- /// </remarks>
- public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
- // Serialize the authorization code, if there is one.
- var authCodeCarrier = message as IAuthorizationCodeCarryingRequest;
- if (authCodeCarrier != null) {
- var codeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer);
- var code = authCodeCarrier.AuthorizationDescription;
- authCodeCarrier.Code = codeFormatter.Serialize(code);
- 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>
- /// <remarks>
- /// Implementations that provide message protection must honor the
- /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
- /// </remarks>
- [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "unauthorizedclient", Justification = "Protocol requirement")]
- [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "incorrectclientcredentials", Justification = "Protocol requirement")]
- [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "authorizationexpired", Justification = "Protocol requirement")]
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "DotNetOpenAuth.Messaging.ErrorUtilities.VerifyProtocol(System.Boolean,System.String,System.Object[])", Justification = "Protocol requirement")]
- public override MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
- var tokenRequest = message as IAuthorizationCarryingRequest;
- if (tokenRequest != null) {
- try {
- var authCodeCarrier = message as IAuthorizationCodeCarryingRequest;
- var refreshTokenCarrier = message as IRefreshTokenCarryingRequest;
- var resourceOwnerPasswordCarrier = message as AccessTokenResourceOwnerPasswordCredentialsRequest;
- var clientCredentialOnly = message as AccessTokenClientCredentialsRequest;
- if (authCodeCarrier != null) {
- var authorizationCodeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer);
- var authorizationCode = authorizationCodeFormatter.Deserialize(message, authCodeCarrier.Code, Protocol.code);
- authCodeCarrier.AuthorizationDescription = authorizationCode;
- } else if (refreshTokenCarrier != null) {
- var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore);
- var refreshToken = refreshTokenFormatter.Deserialize(message, refreshTokenCarrier.RefreshToken, Protocol.refresh_token);
- refreshTokenCarrier.AuthorizationDescription = refreshToken;
- } else if (resourceOwnerPasswordCarrier != null) {
- try {
- if (this.AuthorizationServer.IsResourceOwnerCredentialValid(resourceOwnerPasswordCarrier.UserName, resourceOwnerPasswordCarrier.Password)) {
- resourceOwnerPasswordCarrier.CredentialsValidated = true;
- } else {
- Logger.OAuth.ErrorFormat(
- "Resource owner password credential for user \"{0}\" rejected by authorization server host.",
- resourceOwnerPasswordCarrier.UserName);
- throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.InvalidGrant, AuthServerStrings.InvalidResourceOwnerPasswordCredential);
- }
- } catch (NotSupportedException) {
- throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.UnsupportedGrantType);
- } catch (NotImplementedException) {
- throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.UnsupportedGrantType);
- }
- } else if (clientCredentialOnly != null) {
- // this method will throw later if the credentials are false.
- clientCredentialOnly.CredentialsValidated = true;
- } else {
- throw ErrorUtilities.ThrowInternal("Unexpected message type: " + tokenRequest.GetType());
- }
- } catch (ExpiredMessageException ex) {
- throw new TokenEndpointProtocolException(ex);
- }
-
- var accessRequest = tokenRequest as AccessTokenRequestBase;
- if (accessRequest != null) {
- // Make sure the client sending us this token is the client we issued the token to.
- AuthServerUtilities.TokenEndpointVerify(string.Equals(accessRequest.ClientIdentifier, tokenRequest.AuthorizationDescription.ClientIdentifier, StringComparison.Ordinal), Protocol.AccessTokenRequestErrorCodes.InvalidClient);
-
- var scopedAccessRequest = accessRequest as ScopedAccessTokenRequest;
- if (scopedAccessRequest != null) {
- // Make sure the scope the client is requesting does not exceed the scope in the grant.
- if (!scopedAccessRequest.Scope.IsSubsetOf(tokenRequest.AuthorizationDescription.Scope)) {
- Logger.OAuth.ErrorFormat("The requested access scope (\"{0}\") exceeds the grant scope (\"{1}\").", scopedAccessRequest.Scope, tokenRequest.AuthorizationDescription.Scope);
- throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.InvalidScope, AuthServerStrings.AccessScopeExceedsGrantScope);
- }
- }
- }
-
- // Make sure the authorization this token represents hasn't already been revoked.
- if (!this.AuthorizationServer.IsAuthorizationValid(tokenRequest.AuthorizationDescription)) {
- Logger.OAuth.Error("Rejecting access token request because the IAuthorizationServer.IsAuthorizationValid method returned false.");
- throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.InvalidGrant);
- }
-
- return MessageProtections.None;
- }
-
- return null;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessTokenBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessTokenBindingElement.cs
index 1dd650c..9d7e8f2 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessTokenBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AccessTokenBindingElement.cs
@@ -59,32 +59,18 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
}
}
- AccessToken accessToken = null;
if (authCarryingRequest != null) {
ErrorUtilities.VerifyInternal(request != null, MessagingStrings.UnexpectedMessageReceived, typeof(IAccessTokenRequestInternal), request.GetType());
- accessToken = new AccessToken(authCarryingRequest.AuthorizationDescription, accessTokenResponse.Lifetime);
+ accessTokenResponse.AuthorizationDescription = new AccessToken(authCarryingRequest.AuthorizationDescription, accessTokenResponse.Lifetime);
} else if (implicitGrantResponse != null) {
IAccessTokenCarryingRequest tokenCarryingResponse = implicitGrantResponse;
- accessToken = new AccessToken(
+ accessTokenResponse.AuthorizationDescription = new AccessToken(
request.ClientIdentifier,
implicitGrantResponse.Scope,
implicitGrantResponse.AuthorizingUsername,
implicitGrantResponse.Lifetime);
}
- if (accessToken != null) {
- accessTokenResponse.AuthorizationDescription = accessToken;
- var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServer.AccessTokenSigningKey, request.AccessTokenCreationParameters.ResourceServerEncryptionKey);
- accessTokenResponse.AccessToken = accessTokenFormatter.Serialize(accessToken);
- }
-
- var refreshTokenResponse = message as AccessTokenSuccessResponse;
- if (refreshTokenResponse != null && refreshTokenResponse.HasRefreshToken) {
- var refreshToken = new RefreshToken(authCarryingRequest.AuthorizationDescription);
- var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore);
- refreshTokenResponse.RefreshToken = refreshTokenFormatter.Serialize(refreshToken);
- }
-
return null;
}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
index 3d408ec..43ce243 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
@@ -17,6 +17,11 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
/// A guard for all messages to or from an Authorization Server to ensure that they are well formed,
/// have valid secrets, callback URIs, etc.
/// </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 MessageValidationBindingElement : AuthServerBindingElementBase {
/// <summary>
/// Gets the protection commonly offered (if any) by this binding element.
@@ -72,15 +77,40 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
bool applied = false;
// Check that the client secret is correct for client authenticated messages.
+ var clientCredentialOnly = message as AccessTokenClientCredentialsRequest;
var authenticatedClientRequest = message as AuthenticatedClientRequestBase;
if (authenticatedClientRequest != null) {
var client = this.AuthorizationServer.GetClientOrThrow(authenticatedClientRequest.ClientIdentifier);
string secret = client.Secret;
AuthServerUtilities.TokenEndpointVerify(!string.IsNullOrEmpty(secret), Protocol.AccessTokenRequestErrorCodes.UnauthorizedClient); // an empty secret is not allowed for client authenticated calls.
AuthServerUtilities.TokenEndpointVerify(MessagingUtilities.EqualsConstantTime(secret, authenticatedClientRequest.ClientSecret), Protocol.AccessTokenRequestErrorCodes.InvalidClient, AuthServerStrings.ClientSecretMismatch);
+
+ if (clientCredentialOnly != null) {
+ clientCredentialOnly.CredentialsValidated = true;
+ }
+
applied = true;
}
+ // Check that any resource owner password credential is correct.
+ var resourceOwnerPasswordCarrier = message as AccessTokenResourceOwnerPasswordCredentialsRequest;
+ if (resourceOwnerPasswordCarrier != null) {
+ try {
+ if (this.AuthorizationServer.IsResourceOwnerCredentialValid(resourceOwnerPasswordCarrier.UserName, resourceOwnerPasswordCarrier.Password)) {
+ resourceOwnerPasswordCarrier.CredentialsValidated = true;
+ } else {
+ Logger.OAuth.ErrorFormat(
+ "Resource owner password credential for user \"{0}\" rejected by authorization server host.",
+ resourceOwnerPasswordCarrier.UserName);
+ throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.InvalidGrant, AuthServerStrings.InvalidResourceOwnerPasswordCredential);
+ }
+ } catch (NotSupportedException) {
+ throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.UnsupportedGrantType);
+ } catch (NotImplementedException) {
+ throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.UnsupportedGrantType);
+ }
+ }
+
// Check that authorization requests come with an acceptable callback URI.
var authorizationRequest = message as EndUserAuthorizationRequest;
if (authorizationRequest != null) {
@@ -98,6 +128,32 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
applied = true;
}
+ var authCarrier = message as IAuthorizationCarryingRequest;
+ if (authCarrier != null) {
+ var accessRequest = authCarrier as AccessTokenRequestBase;
+ if (accessRequest != null) {
+ // Make sure the client sending us this token is the client we issued the token to.
+ AuthServerUtilities.TokenEndpointVerify(string.Equals(accessRequest.ClientIdentifier, authCarrier.AuthorizationDescription.ClientIdentifier, StringComparison.Ordinal), Protocol.AccessTokenRequestErrorCodes.InvalidClient);
+
+ var scopedAccessRequest = accessRequest as ScopedAccessTokenRequest;
+ if (scopedAccessRequest != null) {
+ // Make sure the scope the client is requesting does not exceed the scope in the grant.
+ if (!scopedAccessRequest.Scope.IsSubsetOf(authCarrier.AuthorizationDescription.Scope)) {
+ Logger.OAuth.ErrorFormat("The requested access scope (\"{0}\") exceeds the grant scope (\"{1}\").", scopedAccessRequest.Scope, authCarrier.AuthorizationDescription.Scope);
+ throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.InvalidScope, AuthServerStrings.AccessScopeExceedsGrantScope);
+ }
+ }
+ }
+
+ // Make sure the authorization this token represents hasn't already been revoked.
+ if (!this.AuthorizationServer.IsAuthorizationValid(authCarrier.AuthorizationDescription)) {
+ Logger.OAuth.Error("Rejecting access token request because the IAuthorizationServer.IsAuthorizationValid method returned false.");
+ throw new TokenEndpointProtocolException(Protocol.AccessTokenRequestErrorCodes.InvalidGrant);
+ }
+
+ applied = true;
+ }
+
return applied ? (MessageProtections?)MessageProtections.None : null;
}
}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs
index 9c15045..09d35ee 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs
@@ -116,7 +116,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
// The order they are provided is used for outgoing messgaes, and reversed for incoming messages.
bindingElements.Add(new MessageValidationBindingElement());
bindingElements.Add(new AccessTokenBindingElement());
- bindingElements.Add(new AccessRequestBindingElement());
+ bindingElements.Add(new TokenCodeSerializationBindingElement());
return bindingElements.ToArray();
}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs
new file mode 100644
index 0000000..b14f366
--- /dev/null
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/TokenCodeSerializationBindingElement.cs
@@ -0,0 +1,120 @@
+//-----------------------------------------------------------------------
+// <copyright file="TokenCodeSerializationBindingElement.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OAuth2.ChannelElements {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Globalization;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OAuth2.AuthServer.ChannelElements;
+ using DotNetOpenAuth.OAuth2.Messages;
+
+ /// <summary>
+ /// Serializes and deserializes authorization codes, refresh tokens and access tokens
+ /// on incoming and outgoing messages.
+ /// </summary>
+ internal class TokenCodeSerializationBindingElement : AuthServerBindingElementBase {
+ /// <summary>
+ /// Gets the protection commonly offered (if any) by this binding element.
+ /// </summary>
+ /// <value></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>
+ /// <remarks>
+ /// Implementations that provide message protection must honor the
+ /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
+ /// </remarks>
+ public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
+ var directResponse = message as IDirectResponseProtocolMessage;
+ var request = directResponse != null ? directResponse.OriginatingRequest as IAccessTokenRequestInternal : null;
+
+ // Serialize the authorization code, if there is one.
+ var authCodeCarrier = message as IAuthorizationCodeCarryingRequest;
+ if (authCodeCarrier != null) {
+ var codeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer);
+ var code = authCodeCarrier.AuthorizationDescription;
+ authCodeCarrier.Code = codeFormatter.Serialize(code);
+ return MessageProtections.None;
+ }
+
+ // Serialize the refresh token, if applicable.
+ var refreshTokenResponse = message as AccessTokenSuccessResponse;
+ if (refreshTokenResponse != null && refreshTokenResponse.HasRefreshToken) {
+ var refreshTokenCarrier = (IAuthorizationCarryingRequest)message;
+ var refreshToken = new RefreshToken(refreshTokenCarrier.AuthorizationDescription);
+ var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore);
+ refreshTokenResponse.RefreshToken = refreshTokenFormatter.Serialize(refreshToken);
+ }
+
+ // Serialize the access token, if applicable.
+ 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(this.AuthorizationServer.AccessTokenSigningKey, request.AccessTokenCreationParameters.ResourceServerEncryptionKey);
+ accessTokenResponse.AccessToken = accessTokenFormatter.Serialize(accessTokenResponse.AuthorizationDescription);
+ }
+
+ 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>
+ /// <remarks>
+ /// Implementations that provide message protection must honor the
+ /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
+ /// </remarks>
+ [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "unauthorizedclient", Justification = "Protocol requirement")]
+ [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "incorrectclientcredentials", Justification = "Protocol requirement")]
+ [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "authorizationexpired", Justification = "Protocol requirement")]
+ [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "DotNetOpenAuth.Messaging.ErrorUtilities.VerifyProtocol(System.Boolean,System.String,System.Object[])", Justification = "Protocol requirement")]
+ public override MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
+ var authCodeCarrier = message as IAuthorizationCodeCarryingRequest;
+ if (authCodeCarrier != null) {
+ var authorizationCodeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer);
+ var authorizationCode = authorizationCodeFormatter.Deserialize(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);
+ refreshTokenCarrier.AuthorizationDescription = refreshToken;
+ }
+
+ return null;
+ }
+ }
+}