1
//-----------------------------------------------------------------------
2 // <copyright file="BackwardCompatibilityBindingElement.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth
.OpenId
.ChannelElements
{
9 using DotNetOpenAuth
.Messaging
;
10 using DotNetOpenAuth
.Messaging
.Reflection
;
11 using DotNetOpenAuth
.OpenId
.Messages
;
14 /// Provides a mechanism for Relying Parties to work with OpenID 1.0 Providers
15 /// without losing claimed_id and op_endpoint data, which OpenID 2.0 Providers
16 /// are required to send back with positive assertions.
18 internal class BackwardCompatibilityBindingElement
: IChannelBindingElement
{
20 /// The name of the callback parameter that stores the Provider Endpoint URL
21 /// to tack onto the return_to URI.
23 private const string ProviderEndpointParameterName
= "dnoi.op_endpoint";
26 /// The name of the callback parameter that stores the Claimed Identifier
27 /// to tack onto the return_to URI.
29 private const string ClaimedIdentifierParameterName
= "dnoi.claimed_id";
31 #region IChannelBindingElement Members
34 /// Gets or sets the channel that this binding element belongs to.
38 /// This property is set by the channel when it is first constructed.
40 public Channel Channel { get; set; }
43 /// Gets the protection offered (if any) by this binding element.
45 /// <value><see cref="MessageProtections.None"/></value>
46 public MessageProtections Protection
{
47 get { return MessageProtections.None; }
51 /// Prepares a message for sending based on the rules of this channel binding element.
53 /// <param name="message">The message to prepare for sending.</param>
55 /// True if the <paramref name="message"/> applied to this binding element
56 /// and the operation was successful. False otherwise.
59 /// Implementations that provide message protection must honor the
60 /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
62 public bool PrepareMessageForSending(IProtocolMessage message
) {
63 SignedResponseRequest request
= message
as SignedResponseRequest
;
64 if (request
!= null && request
.Version
.Major
< 2) {
65 request
.AddReturnToArguments(ProviderEndpointParameterName
, request
.Recipient
.AbsoluteUri
);
67 CheckIdRequest authRequest
= request
as CheckIdRequest
;
68 if (authRequest
!= null) {
69 request
.AddReturnToArguments(ClaimedIdentifierParameterName
, authRequest
.ClaimedIdentifier
);
79 /// Performs any transformation on an incoming message that may be necessary and/or
80 /// validates an incoming message based on the rules of this channel binding element.
82 /// <param name="message">The incoming message to process.</param>
84 /// True if the <paramref name="message"/> applied to this binding element
85 /// and the operation was successful. False if the operation did not apply to this message.
87 /// <exception cref="ProtocolException">
88 /// Thrown when the binding element rules indicate that this message is invalid and should
92 /// Implementations that provide message protection must honor the
93 /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
95 public bool PrepareMessageForReceiving(IProtocolMessage message
) {
96 IndirectSignedResponse response
= message
as IndirectSignedResponse
;
97 if (response
!= null && response
.Version
.Major
< 2) {
98 var protocol
= Protocol
.Lookup(response
.Version
);
100 // Although GetReturnToArgument may return null if the parameters are not signed,
101 // the ReturnToSignatureBindingElement should have thrown an exception already
102 // if this is a 1.0 OP signed response without a valid signature since 1.0 OPs
103 // are not supposed to be able to send unsolicited assertions.
104 // Any safe solicited assertion would include our signature, allowing us to find
106 if (response
.ProviderEndpoint
== null) {
107 string op_endpoint
= response
.GetReturnToArgument(ProviderEndpointParameterName
);
108 response
.ProviderEndpoint
= new Uri(op_endpoint
);
111 PositiveAssertionResponse authResponse
= response
as PositiveAssertionResponse
;
112 if (authResponse
!= null) {
113 if (authResponse
.ClaimedIdentifier
== null) {
114 authResponse
.ClaimedIdentifier
= response
.GetReturnToArgument(ClaimedIdentifierParameterName
);