diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-12-15 22:17:20 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2009-12-15 22:17:20 -0800 |
commit | e12782c1a6727390b2107ff2e39d4ac6173d86fc (patch) | |
tree | 3be0ccda0a9425927263f5b6b9616ef8ba11ac08 /src/DotNetOpenId/Provider | |
parent | 078b1f350eb40ceee7423c25b1d833dd1f242da4 (diff) | |
parent | a545f7be2693596fa14540c359e43150a6a7cf88 (diff) | |
download | DotNetOpenAuth-origin/mono.zip DotNetOpenAuth-origin/mono.tar.gz DotNetOpenAuth-origin/mono.tar.bz2 |
Merge branch 'v2.5' into monoorigin/mono
Conflicts:
src/DotNetOpenId/Properties/AssemblyInfo.cs
src/DotNetOpenId/RelyingParty/AuthenticationResponse.cs
Diffstat (limited to 'src/DotNetOpenId/Provider')
-rw-r--r-- | src/DotNetOpenId/Provider/AssertionMessage.cs | 21 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/AssociateRequest.cs | 7 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/CheckAuthRequest.cs | 8 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/CheckIdRequest.cs | 89 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/FaultyRequest.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/IAuthenticationRequest.cs | 43 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/IdentityEndpoint.cs | 144 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/OpenIdProvider.cs | 43 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/ProviderEndpoint.cs | 21 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/ProviderSecuritySettings.cs | 26 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/ProviderSession.cs | 10 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/Request.cs | 42 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/Signatory.cs | 40 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/SigningMessageEncoder.cs | 12 |
14 files changed, 403 insertions, 105 deletions
diff --git a/src/DotNetOpenId/Provider/AssertionMessage.cs b/src/DotNetOpenId/Provider/AssertionMessage.cs index 3224c61..b238595 100644 --- a/src/DotNetOpenId/Provider/AssertionMessage.cs +++ b/src/DotNetOpenId/Provider/AssertionMessage.cs @@ -13,7 +13,9 @@ namespace DotNetOpenId.Provider { message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.id_res;
message.Fields[protocol.openidnp.identity] = localIdentifier;
- message.Fields[protocol.openidnp.return_to] = message.RedirectUrl.AbsoluteUri;
+ // We use OriginalString for the return_to to help protect against interop
+ // problems with RPs that require an explicit port, or who knows what else.
+ message.Fields[protocol.openidnp.return_to] = message.RedirectUrl.OriginalString;
message.Signed.AddRange(new[]{
protocol.openidnp.return_to,
protocol.openidnp.identity,
@@ -34,16 +36,17 @@ namespace DotNetOpenId.Provider { // as appropriate by the Signatory.Sign method.
}
- public static void CreateNegativeAssertion(EncodableResponse message,
- bool immediateMode, Uri setupUrl) {
+ public static void CreateNegativeAssertion(EncodableResponse message, CheckIdRequest request) {
if (message == null) throw new ArgumentNullException("message");
+ if (request == null) throw new ArgumentNullException("request");
+
Protocol protocol = message.Protocol;
- if (immediateMode) {
+ if (request.Immediate) {
if (protocol.Version.Major >= 2) {
message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.setup_needed;
} else {
message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.id_res;
- message.Fields[protocol.openidnp.user_setup_url] = setupUrl.AbsoluteUri;
+ message.Fields[protocol.openidnp.user_setup_url] = request.SetupUrl.AbsoluteUri;
}
} else {
message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.cancel;
@@ -58,12 +61,10 @@ namespace DotNetOpenId.Provider { if (request.IsAuthenticated.Value) {
AssertionMessage.CreatePositiveAssertion(response, request.Provider,
request.LocalIdentifier, request.ClaimedIdentifier);
- if (TraceUtil.Switch.TraceInfo)
- Trace.TraceInformation("Created positive assertion for {0}.", request.ClaimedIdentifier);
+ Logger.InfoFormat("Created positive assertion for {0}.", request.ClaimedIdentifier);
} else {
- AssertionMessage.CreateNegativeAssertion(response, request.Immediate, request.SetupUrl);
- if (TraceUtil.Switch.TraceInfo)
- Trace.TraceInformation("Created negative assertion for {0}.", request.ClaimedIdentifier);
+ AssertionMessage.CreateNegativeAssertion(response, request);
+ Logger.InfoFormat("Created negative assertion for {0}.", request.ClaimedIdentifier);
}
return response;
}
diff --git a/src/DotNetOpenId/Provider/AssociateRequest.cs b/src/DotNetOpenId/Provider/AssociateRequest.cs index 669ab71..a2f6f9a 100644 --- a/src/DotNetOpenId/Provider/AssociateRequest.cs +++ b/src/DotNetOpenId/Provider/AssociateRequest.cs @@ -28,7 +28,7 @@ namespace DotNetOpenId.Provider { }
/// <summary>
- /// Used to throw a carefully crafted exception that will end up getting
+ /// This method is used to throw a carefully crafted exception that will end up getting
/// encoded as a response to the RP, given hints as to what
/// assoc_type and session_type args we support.
/// </summary>
@@ -74,13 +74,12 @@ namespace DotNetOpenId.Provider { response.Fields[pair.Key] = nvc[pair.Key];
}
- if (TraceUtil.Switch.TraceInfo)
- Trace.TraceInformation("Association {0} created.", assoc.Handle);
+ Logger.InfoFormat("Association {0} created.", assoc.Handle);
return response;
}
- internal override IEncodable CreateResponse() {
+ protected override IEncodable CreateResponse() {
return Answer();
}
diff --git a/src/DotNetOpenId/Provider/CheckAuthRequest.cs b/src/DotNetOpenId/Provider/CheckAuthRequest.cs index a6ec0ca..bda4918 100644 --- a/src/DotNetOpenId/Provider/CheckAuthRequest.cs +++ b/src/DotNetOpenId/Provider/CheckAuthRequest.cs @@ -24,7 +24,7 @@ namespace DotNetOpenId.Provider { signedFields = new Dictionary<string, string>();
Debug.Assert(!signedKeyOrder.Contains(Protocol.openidnp.mode), "openid.mode must not be included in signature because it necessarily changes in checkauth requests.");
foreach (string key in signedKeyOrder) {
- signedFields.Add(key, Util.GetRequiredArg(Query, Protocol.openid.Prefix + key));
+ signedFields.Add(key, Util.GetRequiredArgAllowEmptyValue(Query, Protocol.openid.Prefix + key));
}
}
@@ -62,9 +62,7 @@ namespace DotNetOpenId.Provider { Association assoc = Provider.Signatory.GetAssociation(invalidate_handle, AssociationRelyingPartyType.Smart);
if (assoc == null) {
- if (TraceUtil.Switch.TraceWarning) {
- Trace.TraceWarning("No matching association found. Returning invalidate_handle. ");
- }
+ Logger.Warn("No matching association found. Returning invalidate_handle. ");
response.Fields[Protocol.openidnp.invalidate_handle] = invalidate_handle;
}
}
@@ -72,7 +70,7 @@ namespace DotNetOpenId.Provider { return response;
}
- internal override IEncodable CreateResponse() {
+ protected override IEncodable CreateResponse() {
return Answer();
}
diff --git a/src/DotNetOpenId/Provider/CheckIdRequest.cs b/src/DotNetOpenId/Provider/CheckIdRequest.cs index e71049c..98d7428 100644 --- a/src/DotNetOpenId/Provider/CheckIdRequest.cs +++ b/src/DotNetOpenId/Provider/CheckIdRequest.cs @@ -62,8 +62,7 @@ namespace DotNetOpenId.Provider { // The spec requires that the return_to URLs given in an RPs XRDS doc
// do not contain wildcards.
if (discoveredReturnToUrl.DomainWildcard) {
- if (TraceUtil.Switch.TraceWarning)
- Trace.TraceWarning("Realm {0} contained return_to URL {1} which contains a wildcard, which is not allowed.",
+ Logger.WarnFormat("Realm {0} contained return_to URL {1} which contains a wildcard, which is not allowed.",
Realm, discoveredReturnToUrl);
continue;
}
@@ -75,13 +74,11 @@ namespace DotNetOpenId.Provider { }
}
} catch (OpenIdException ex) {
- if (TraceUtil.Switch.TraceInfo)
- Trace.TraceInformation("Relying party discovery at URL {0} failed. {1}",
+ Logger.InfoFormat("Relying party discovery at URL {0} failed. {1}",
Realm, ex);
// Don't do anything else. We quietly fail at return_to verification and return false.
} catch (WebException ex) {
- if (TraceUtil.Switch.TraceInfo)
- Trace.TraceInformation("Relying party discovery at URL {0} failed. {1}",
+ Logger.InfoFormat("Relying party discovery at URL {0} failed. {1}",
Realm, ex);
// Don't do anything else. We quietly fail at return_to verification and return false.
}
@@ -94,6 +91,17 @@ namespace DotNetOpenId.Provider { /// to send back to the relying party.
/// </summary>
public bool IsDirectedIdentity { get; private set; }
+ /// <summary>
+ /// A value indicating whether the requesting Relying Party is using a delegated URL.
+ /// </summary>
+ /// <remarks>
+ /// When delegated identifiers are used, the <see cref="ClaimedIdentifier"/> should not
+ /// be changed at the Provider during authentication.
+ /// Delegation is only detectable on requests originating from OpenID 2.0 relying parties.
+ /// A relying party implementing only OpenID 1.x may use delegation and this property will
+ /// return false anyway.
+ /// </remarks>
+ public bool IsDelegatedIdentifier { get; private set; }
Identifier localIdentifier;
/// <summary>
/// The user identifier used by this particular provider.
@@ -101,17 +109,16 @@ namespace DotNetOpenId.Provider { public Identifier LocalIdentifier {
get { return localIdentifier; }
set {
+ // Keep LocalIdentifier and ClaimedIdentifier in sync for directed identity.
if (IsDirectedIdentity) {
- // Keep LocalIdentifier and ClaimedIdentifier in sync
if (ClaimedIdentifier != null && ClaimedIdentifier != value) {
throw new InvalidOperationException(Strings.IdentifierSelectRequiresMatchingIdentifiers);
- } else {
- localIdentifier = value;
- claimedIdentifier = value;
}
- } else {
- throw new InvalidOperationException(Strings.IdentifierSelectModeOnly);
+
+ claimedIdentifier = value;
}
+
+ localIdentifier = value;
}
}
Identifier claimedIdentifier;
@@ -121,19 +128,53 @@ namespace DotNetOpenId.Provider { public Identifier ClaimedIdentifier {
get { return claimedIdentifier; }
set {
+ // Keep LocalIdentifier and ClaimedIdentifier in sync for directed identity.
if (IsDirectedIdentity) {
- // Keep LocalIdentifier and ClaimedIdentifier in sync
if (LocalIdentifier != null && LocalIdentifier != value) {
throw new InvalidOperationException(Strings.IdentifierSelectRequiresMatchingIdentifiers);
- } else {
- claimedIdentifier = value;
- localIdentifier = value;
}
- } else {
- throw new InvalidOperationException(Strings.IdentifierSelectModeOnly);
+
+ localIdentifier = value;
+ }
+
+ if (IsDelegatedIdentifier) {
+ throw new InvalidOperationException(Strings.ClaimedIdentifierCannotBeSetOnDelegatedAuthentication);
}
+
+ claimedIdentifier = value;
}
}
+
+ /// <summary>
+ /// Adds an optional fragment (#fragment) portion to a URI ClaimedIdentifier.
+ /// Useful for identifier recycling.
+ /// </summary>
+ /// <param name="fragment">
+ /// Should not include the # prefix character as that will be added internally.
+ /// May be null or the empty string to clear a previously set fragment.
+ /// </param>
+ /// <remarks>
+ /// <para>Unlike the <see cref="ClaimedIdentifier"/> property, which can only be set if
+ /// using directed identity, this method can be called on any URI claimed identifier.</para>
+ /// <para>Because XRI claimed identifiers (the canonical IDs) are never recycled,
+ /// this method should<i>not</i> be called for XRIs.</para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when this method is called on an XRI, or on a directed identity request
+ /// before the <see cref="ClaimedIdentifier"/> property is set.</exception>
+ public void SetClaimedIdentifierFragment(string fragment) {
+ if (IsDirectedIdentity && ClaimedIdentifier == null) {
+ throw new InvalidOperationException(Strings.ClaimedIdentifierMustBeSetFirst);
+ }
+ if (ClaimedIdentifier is XriIdentifier) {
+ throw new InvalidOperationException(Strings.FragmentNotAllowedOnXRIs);
+ }
+
+ UriBuilder builder = new UriBuilder(ClaimedIdentifier);
+ builder.Fragment = fragment;
+ claimedIdentifier = builder.Uri;
+ }
+
/// <summary>
/// The URL to redirect the user agent to after the authentication attempt.
/// This must fall "under" the realm URL.
@@ -218,18 +259,28 @@ namespace DotNetOpenId.Provider { claimedIdentifier = null;
localIdentifier = null;
}
+
+ // URL delegation is only detectable from 2.0 RPs, since openid.claimed_id isn't included from 1.0 RPs.
+ // If the openid.claimed_id is present, and if it's different than the openid.identity argument, then
+ // the RP has discovered a claimed identifier that has delegated authentication to this Provider.
+ IsDelegatedIdentifier = ClaimedIdentifier != null && ClaimedIdentifier != LocalIdentifier;
}
- internal override IEncodable CreateResponse() {
+ protected override IEncodable CreateResponse() {
Debug.Assert(IsAuthenticated.HasValue, "This should be checked internally before CreateResponse is called.");
return AssertionMessage.CreateAssertion(this);
}
/// <summary>
/// Encode this request as a URL to GET.
+ /// Only used in response to immediate auth requests from OpenID 1.x RPs.
/// </summary>
internal Uri SetupUrl {
get {
+ if (Protocol.Version.Major >= 2) {
+ Debug.Fail("This property only applicable to OpenID 1.x RPs.");
+ throw new InvalidOperationException();
+ }
Debug.Assert(Provider.Endpoint != null, "The OpenIdProvider should have guaranteed this.");
var q = new Dictionary<string, string>();
diff --git a/src/DotNetOpenId/Provider/FaultyRequest.cs b/src/DotNetOpenId/Provider/FaultyRequest.cs index 2d38a50..c2e3b3a 100644 --- a/src/DotNetOpenId/Provider/FaultyRequest.cs +++ b/src/DotNetOpenId/Provider/FaultyRequest.cs @@ -18,7 +18,7 @@ namespace DotNetOpenId.Provider { get { return true; }
}
- internal override IEncodable CreateResponse() {
+ protected override IEncodable CreateResponse() {
return Response;
}
}
diff --git a/src/DotNetOpenId/Provider/IAuthenticationRequest.cs b/src/DotNetOpenId/Provider/IAuthenticationRequest.cs index 7e0fd1c..56b5fc3 100644 --- a/src/DotNetOpenId/Provider/IAuthenticationRequest.cs +++ b/src/DotNetOpenId/Provider/IAuthenticationRequest.cs @@ -10,6 +10,10 @@ namespace DotNetOpenId.Provider { /// </summary>
public interface IAuthenticationRequest : IRequest {
/// <summary>
+ /// Gets the version of OpenID being used by the relying party that sent the request.
+ /// </summary>
+ ProtocolVersion RelyingPartyVersion { get; }
+ /// <summary>
/// Whether the consumer demands an immediate response.
/// If false, the consumer is willing to wait for the identity provider
/// to authenticate the user.
@@ -36,6 +40,17 @@ namespace DotNetOpenId.Provider { /// </summary>
bool IsDirectedIdentity { get; }
/// <summary>
+ /// A value indicating whether the requesting Relying Party is using a delegated URL.
+ /// </summary>
+ /// <remarks>
+ /// When delegated identifiers are used, the <see cref="ClaimedIdentifier"/> should not
+ /// be changed at the Provider during authentication.
+ /// Delegation is only detectable on requests originating from OpenID 2.0 relying parties.
+ /// A relying party implementing only OpenID 1.x may use delegation and this property will
+ /// return false anyway.
+ /// </remarks>
+ bool IsDelegatedIdentifier { get; }
+ /// <summary>
/// The Local Identifier to this OpenID Provider of the user attempting
/// to authenticate. Check <see cref="IsDirectedIdentity"/> to see if
/// this value is valid.
@@ -54,14 +69,34 @@ namespace DotNetOpenId.Provider { /// Check <see cref="IsDirectedIdentity"/> to see if this value is valid.
/// </summary>
/// <remarks>
- /// This will not be the same as this provider's local identifier for the user
+ /// <para>This property can only be set if <see cref="IsDelegatedIdentifier"/> is
+ /// false, to prevent breaking URL delegation.</para>
+ /// <para>This will not be the same as this provider's local identifier for the user
/// if the user has set up his/her own identity page that points to this
- /// provider for authentication.
- /// The provider may use this identifier for displaying to the user when
- /// asking for the user's permission to authenticate to the relying party.
+ /// provider for authentication.</para>
+ /// <para>The provider may use this identifier for displaying to the user when
+ /// asking for the user's permission to authenticate to the relying party.</para>
/// </remarks>
+ /// <exception cref="InvalidOperationException">Thrown from the setter
+ /// if <see cref="IsDelegatedIdentifier"/> is true.</exception>
Identifier ClaimedIdentifier { get; set; }
/// <summary>
+ /// Adds an optional fragment (#fragment) portion to the ClaimedIdentifier.
+ /// Useful for identifier recycling.
+ /// </summary>
+ /// <param name="fragment">
+ /// Should not include the # prefix character as that will be added internally.
+ /// May be null or the empty string to clear a previously set fragment.
+ /// </param>
+ /// <remarks>
+ /// <para>Unlike the <see cref="ClaimedIdentifier"/> property, which can only be set if
+ /// using directed identity, this method can be called on any URI claimed identifier.</para>
+ /// <para>Because XRI claimed identifiers (the canonical IDs) are never recycled,
+ /// this method should<i>not</i> be called for XRIs.</para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">Thrown when this method is called on an XRI.</exception>
+ void SetClaimedIdentifierFragment(string fragment);
+ /// <summary>
/// Gets/sets whether the provider has determined that the
/// <see cref="ClaimedIdentifier"/> belongs to the currently logged in user
/// and wishes to share this information with the consumer.
diff --git a/src/DotNetOpenId/Provider/IdentityEndpoint.cs b/src/DotNetOpenId/Provider/IdentityEndpoint.cs index 18562a6..dd7e30d 100644 --- a/src/DotNetOpenId/Provider/IdentityEndpoint.cs +++ b/src/DotNetOpenId/Provider/IdentityEndpoint.cs @@ -1,13 +1,60 @@ using System;
-using System.Collections.Generic;
using System.ComponentModel;
-using System.Text;
-using System.Web;
using System.Web.UI;
-using System.Web.UI.WebControls;
namespace DotNetOpenId.Provider {
/// <summary>
+ /// The event arguments passed to the <see cref="IdentityEndpoint.NormalizeUri"/> event handler.
+ /// </summary>
+ public class IdentityEndpointNormalizationEventArgs : EventArgs {
+ internal IdentityEndpointNormalizationEventArgs(UriIdentifier userSuppliedIdentifier) {
+ UserSuppliedIdentifier = userSuppliedIdentifier;
+ }
+
+ /// <summary>
+ /// Gets or sets the portion of the incoming page request URI that is relevant to normalization.
+ /// </summary>
+ /// <remarks>
+ /// This identifier should be used to look up the user whose identity page is being queried.
+ /// It MAY be set in case some clever web server URL rewriting is taking place that ASP.NET
+ /// does not know about but your site does. If this is the case this property should be set
+ /// to whatever the original request URL was.
+ /// </remarks>
+ public Uri UserSuppliedIdentifier { get; set; }
+
+ /// <summary>
+ /// Gets/sets the normalized form of the user's identifier, according to the host site's policy.
+ /// </summary>
+ /// <remarks>
+ /// <para>This should be set to some constant value for an individual user.
+ /// For example, if <see cref="UserSuppliedIdentifier"/> indicates that identity page
+ /// for "BOB" is being called up, then the following things should be considered:</para>
+ /// <list>
+ /// <item>Normalize the capitalization of the URL: for example, change http://provider/BOB to
+ /// http://provider/bob.</item>
+ /// <item>Switch to HTTPS is it is offered: change http://provider/bob to https://provider/bob.</item>
+ /// <item>Strip off the query string if it is not part of the canonical identity:
+ /// https://provider/bob?timeofday=now becomes https://provider/bob</item>
+ /// <item>Ensure that any trailing slash is either present or absent consistently. For example,
+ /// change https://provider/bob/ to https://provider/bob.</item>
+ /// </list>
+ /// <para>When this property is set, the <see cref="IdentityEndpoint"/> control compares it to
+ /// the request that actually came in, and redirects the browser to use the normalized identifier
+ /// if necessary.</para>
+ /// <para>Using the normalized identifier in the request is <i>very</i> important as it
+ /// helps the user maintain a consistent identity across sites and across site visits to an individual site.
+ /// For example, without normalizing the URL, Bob might sign into a relying party site as
+ /// http://provider/bob one day and https://provider/bob the next day, and the relying party
+ /// site <i>should</i> interpret Bob as two different people because the URLs are different.
+ /// By normalizing the URL at the Provider's identity page for Bob, whichever URL Bob types in
+ /// from day-to-day gets redirected to a normalized form, so Bob is seen as the same person
+ /// all the time, which is of course what Bob wants.
+ /// </para>
+ /// </remarks>
+ public Uri NormalizedIdentifier { get; set; }
+ }
+
+ /// <summary>
/// An ASP.NET control that manages the OpenID identity advertising tags
/// of a user's Identity Page that allow a relying party web site to discover
/// how to authenticate a user.
@@ -26,6 +73,7 @@ namespace DotNetOpenId.Provider { /// </summary>
[Category("Behavior")]
[DefaultValue(providerVersionDefault)]
+ [Description("The OpenID version supported by the provider.")]
public ProtocolVersion ProviderVersion {
get {
return ViewState[providerVersionViewStateKey] == null ?
@@ -40,6 +88,7 @@ namespace DotNetOpenId.Provider { /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings"), Bindable(true)]
[Category("Behavior")]
+ [Description("The Provider URL that processes OpenID requests.")]
public string ProviderEndpointUrl {
get { return (string)ViewState[providerEndpointUrlViewStateKey]; }
set {
@@ -54,6 +103,7 @@ namespace DotNetOpenId.Provider { /// </summary>
[Bindable(true)]
[Category("Behavior")]
+ [Description("The user Identifier that is controlled by the Provider.")]
public string ProviderLocalIdentifier {
get { return (string)ViewState[providerLocalIdentifierViewStateKey]; }
set {
@@ -61,6 +111,25 @@ namespace DotNetOpenId.Provider { ViewState[providerLocalIdentifierViewStateKey] = value;
}
}
+
+ const string autoNormalizeRequestViewStateKey = "AutoNormalizeRequest";
+ /// <summary>
+ /// Whether every incoming request will be checked for normalized form and redirected if it is not.
+ /// </summary>
+ /// <remarks>
+ /// <para>If set to true (and it should be), you should also handle the <see cref="NormalizeUri"/>
+ /// event and apply your own policy for normalizing the URI.</para>
+ /// If multiple <see cref="IdentityEndpoint"/> controls are on a single page (to support
+ /// multiple versions of OpenID for example) then only one of them should have this
+ /// property set to true.
+ /// </remarks>
+ [Bindable(true)]
+ [Category("Behavior")]
+ [Description("Whether every incoming request will be checked for normalized form and redirected if it is not. If set to true, consider handling the NormalizeUri event.")]
+ public bool AutoNormalizeRequest {
+ get { return (bool)(ViewState[autoNormalizeRequestViewStateKey] ?? false); }
+ set { ViewState[autoNormalizeRequestViewStateKey] = value; }
+ }
#endregion
internal Protocol Protocol {
@@ -68,6 +137,69 @@ namespace DotNetOpenId.Provider { }
/// <summary>
+ /// Fired at each page request so the host web site can return the normalized
+ /// version of the request URI.
+ /// </summary>
+ public event EventHandler<IdentityEndpointNormalizationEventArgs> NormalizeUri;
+
+ /// <summary>
+ /// Checks the incoming request and invokes a browser redirect if the URL has not been normalized.
+ /// </summary>
+ /// <seealso cref="IdentityEndpointNormalizationEventArgs.NormalizedIdentifier"/>
+ protected virtual void OnNormalize() {
+ UriIdentifier userSuppliedIdentifier = Util.GetRequestUrlFromContext();
+ var normalizationArgs = new IdentityEndpointNormalizationEventArgs(userSuppliedIdentifier);
+
+ var normalizeUri = NormalizeUri;
+ if (normalizeUri != null) {
+ normalizeUri(this, normalizationArgs);
+ } else {
+ // Do some best-guess normalization.
+ normalizationArgs.NormalizedIdentifier = bestGuessNormalization(normalizationArgs.UserSuppliedIdentifier);
+ }
+ // If we have a normalized form, we should use it.
+ // We compare path and query with case sensitivity and host name without case sensitivity deliberately,
+ // and the fragment will be asserted or cleared by the OP during authentication.
+ if (normalizationArgs.NormalizedIdentifier != null &&
+ (!String.Equals(normalizationArgs.NormalizedIdentifier.Host, normalizationArgs.UserSuppliedIdentifier.Host, StringComparison.OrdinalIgnoreCase) ||
+ !String.Equals(normalizationArgs.NormalizedIdentifier.PathAndQuery, normalizationArgs.UserSuppliedIdentifier.PathAndQuery, StringComparison.Ordinal))) {
+ Page.Response.Redirect(normalizationArgs.NormalizedIdentifier.AbsoluteUri);
+ }
+ }
+
+ /// <summary>
+ /// Normalizes the URL by making the path and query lowercase, and trimming trailing slashes.
+ /// </summary>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification="FxCop is probably right, but we've been lowercasing host names for normalization elsewhere in the project for a long time now.")]
+ private static Uri bestGuessNormalization(Uri uri) {
+ UriBuilder uriBuilder = new UriBuilder(uri);
+ uriBuilder.Path = uriBuilder.Path.ToLowerInvariant();
+ // Ensure no trailing slash unless it is the only element of the path.
+ if (uriBuilder.Path != "/") {
+ uriBuilder.Path = uriBuilder.Path.TrimEnd('/');
+ }
+ // We trim the ? from the start of the query when we reset it because
+ // the UriBuilder.Query setter automatically prepends one, and we don't
+ // want to double them up.
+ uriBuilder.Query = uriBuilder.Query.TrimStart('?').ToLowerInvariant();
+ return uriBuilder.Uri;
+ }
+
+ /// <summary>
+ /// Checks the incoming request and invokes a browser redirect if the URL has not been normalized.
+ /// </summary>
+ protected override void OnLoad(EventArgs e) {
+ // Perform URL normalization BEFORE calling base.OnLoad, to keep
+ // our base XrdsPublisher from over-eagerly responding with an XRDS
+ // document before we've redirected.
+ if (AutoNormalizeRequest && !Page.IsPostBack) {
+ OnNormalize();
+ }
+
+ base.OnLoad(e);
+ }
+
+ /// <summary>
/// Renders OpenID identity tags.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings")]
@@ -77,7 +209,7 @@ namespace DotNetOpenId.Provider { writer.WriteBeginTag("link");
writer.WriteAttribute("rel", Protocol.HtmlDiscoveryProviderKey);
writer.WriteAttribute("href",
- new Uri(Page.Request.Url, Page.ResolveUrl(ProviderEndpointUrl)).AbsoluteUri);
+ new Uri(Util.GetRequestUrlFromContext(), Page.ResolveUrl(ProviderEndpointUrl)).AbsoluteUri);
writer.Write(">");
writer.WriteEndTag("link");
writer.WriteLine();
@@ -86,7 +218,7 @@ namespace DotNetOpenId.Provider { writer.WriteBeginTag("link");
writer.WriteAttribute("rel", Protocol.HtmlDiscoveryLocalIdKey);
writer.WriteAttribute("href",
- new Uri(Page.Request.Url, Page.ResolveUrl(ProviderLocalIdentifier)).AbsoluteUri);
+ new Uri(Util.GetRequestUrlFromContext(), Page.ResolveUrl(ProviderLocalIdentifier)).AbsoluteUri);
writer.Write(">");
writer.WriteEndTag("link");
writer.WriteLine();
diff --git a/src/DotNetOpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenId/Provider/OpenIdProvider.cs index e0b2afd..29318a7 100644 --- a/src/DotNetOpenId/Provider/OpenIdProvider.cs +++ b/src/DotNetOpenId/Provider/OpenIdProvider.cs @@ -1,12 +1,12 @@ using System;
+using System.Collections.Generic;
using System.Collections.Specialized;
-using System.Text;
+using System.Configuration;
+using System.Diagnostics;
using System.Web;
using IProviderAssociationStore = DotNetOpenId.IAssociationStore<DotNetOpenId.AssociationRelyingPartyType>;
using ProviderMemoryStore = DotNetOpenId.AssociationMemoryStore<DotNetOpenId.AssociationRelyingPartyType>;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Net;
+using DotNetOpenId.Configuration;
namespace DotNetOpenId.Provider {
/// <summary>
@@ -35,6 +35,10 @@ namespace DotNetOpenId.Provider { /// </summary>
internal Protocol Protocol { get; private set; }
+ internal static Uri DefaultProviderEndpoint { get { return getProviderEndpointFromContext(); } }
+ internal static Uri DefaultRequestUrl { get { return Util.GetRequestUrlFromContext(); } }
+ internal static NameValueCollection DefaultQuery { get { return Util.GetQueryOrFormFromContextNVC(); } }
+
/// <summary>
/// Constructs an OpenId server that uses the HttpApplication dictionary as
/// its association store and detects common settings.
@@ -43,8 +47,8 @@ namespace DotNetOpenId.Provider { /// This method requires a current ASP.NET HttpContext.
/// </remarks>
public OpenIdProvider()
- : this(HttpApplicationStore,
- getProviderEndpointFromContext(), Util.GetRequestUrlFromContext(), Util.GetQueryFromContext()) { }
+ : this(Configuration.Store.CreateInstanceOfStore(HttpApplicationStore),
+ getProviderEndpointFromContext(), Util.GetRequestUrlFromContext(), Util.GetQueryOrFormFromContext()) { }
/// <summary>
/// Constructs an OpenId server that uses a given query and IAssociationStore.
/// </summary>
@@ -67,6 +71,7 @@ namespace DotNetOpenId.Provider { if (providerEndpoint == null) throw new ArgumentNullException("providerEndpoint");
if (requestUrl == null) throw new ArgumentNullException("requestUrl");
if (query == null) throw new ArgumentNullException("query");
+ Settings = new ProviderSecuritySettings();
Endpoint = providerEndpoint;
RequestUrl = requestUrl;
Query = query;
@@ -83,6 +88,13 @@ namespace DotNetOpenId.Provider { /// </remarks>
internal Uri Endpoint { get; private set; }
+ // TODO: make this property public WHEN its security settings are actually supported.
+ /// <summary>
+ /// Provides access to the adjustable security settings of this instance
+ /// of <see cref="OpenIdProvider"/>.
+ /// </summary>
+ internal ProviderSecuritySettings Settings { get; private set; }
+
bool requestProcessed;
Request request;
/// <summary>
@@ -116,8 +128,8 @@ namespace DotNetOpenId.Provider { Protocol = Protocol.Detect(Query);
Request req = Provider.Request.CreateRequest(this);
- if (TraceUtil.Switch.TraceInfo)
- Trace.TraceInformation("Received OpenID {0} request.", req.Mode);
+ Logger.InfoFormat("Received OpenID {0} request.{1}{2}", req.Mode, Environment.NewLine,
+ Util.ToString(Query));
return req;
}
@@ -150,6 +162,8 @@ namespace DotNetOpenId.Provider { if (relyingParty == null) throw new ArgumentNullException("relyingParty");
if (claimedIdentifier == null) throw new ArgumentNullException("claimedIdentifier");
if (localIdentifier == null) throw new ArgumentNullException("localIdentifier");
+
+ Logger.InfoFormat("Preparing unsolicited assertion for {0}", claimedIdentifier);
return AssertionMessage.CreateUnsolicitedAssertion(this,
relyingParty, claimedIdentifier, localIdentifier);
}
@@ -182,10 +196,21 @@ namespace DotNetOpenId.Provider { HttpContext context = HttpContext.Current;
if (context == null)
throw new InvalidOperationException(Strings.HttpContextRequiredForThisOverload);
- UriBuilder builder = new UriBuilder(HttpContext.Current.Request.Url);
+ UriBuilder builder = new UriBuilder(Util.GetRequestUrlFromContext());
builder.Query = null;
builder.Fragment = null;
return builder.Uri;
}
+
+ /// <summary>
+ /// Gets the relevant Configuration section for this OpenIdRelyingParty.
+ /// </summary>
+ /// <remarks>
+ /// This is not a static member because depending on the context within which we are
+ /// invoked, the configuration section might be different. (location tag, for example).
+ /// </remarks>
+ internal static ProviderSection Configuration {
+ get { return ProviderSection.Configuration; }
+ }
}
}
diff --git a/src/DotNetOpenId/Provider/ProviderEndpoint.cs b/src/DotNetOpenId/Provider/ProviderEndpoint.cs index d46d248..40d8dea 100644 --- a/src/DotNetOpenId/Provider/ProviderEndpoint.cs +++ b/src/DotNetOpenId/Provider/ProviderEndpoint.cs @@ -5,6 +5,7 @@ using System.Text; using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
+using IProviderAssociationStore = DotNetOpenId.IAssociationStore<DotNetOpenId.AssociationRelyingPartyType>;
namespace DotNetOpenId.Provider {
/// <summary>
@@ -27,7 +28,7 @@ namespace DotNetOpenId.Provider { /// before responding to the relying party's authentication request.
/// </remarks>
public static IAuthenticationRequest PendingAuthenticationRequest {
- get { return HttpContext.Current.Session[pendingAuthenticationRequestKey] as CheckIdRequest; }
+ get { return HttpContext.Current.Session[pendingAuthenticationRequestKey] as IAuthenticationRequest; }
set { HttpContext.Current.Session[pendingAuthenticationRequestKey] = value; }
}
@@ -48,6 +49,15 @@ namespace DotNetOpenId.Provider { }
/// <summary>
+ /// A custom application store to use. Null to use the default.
+ /// </summary>
+ /// <remarks>
+ /// If set, this property must be set in each Page Load event
+ /// as it is not persisted across postbacks.
+ /// </remarks>
+ public IProviderAssociationStore CustomApplicationStore { get; set; }
+
+ /// <summary>
/// Checks for incoming OpenID requests, responds to ones it can
/// respond to without policy checks, and fires events for custom
/// handling of the ones it cannot decide on automatically.
@@ -56,7 +66,14 @@ namespace DotNetOpenId.Provider { base.OnLoad(e);
if (Enabled) {
- OpenIdProvider provider = new OpenIdProvider();
+ // Use the explicitly given state store on this control if there is one.
+ // Then try the configuration file specified one. Finally, use the default
+ // in-memory one that's built into OpenIdProvider.
+ OpenIdProvider provider = new OpenIdProvider(
+ CustomApplicationStore ?? OpenIdProvider.Configuration.Store.CreateInstanceOfStore(OpenIdProvider.HttpApplicationStore),
+ OpenIdProvider.DefaultProviderEndpoint,
+ OpenIdProvider.DefaultRequestUrl,
+ OpenIdProvider.DefaultQuery);
// determine what incoming message was received
if (provider.Request != null) {
diff --git a/src/DotNetOpenId/Provider/ProviderSecuritySettings.cs b/src/DotNetOpenId/Provider/ProviderSecuritySettings.cs new file mode 100644 index 0000000..88c1e07 --- /dev/null +++ b/src/DotNetOpenId/Provider/ProviderSecuritySettings.cs @@ -0,0 +1,26 @@ +using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace DotNetOpenId.Provider {
+ sealed class ProviderSecuritySettings : SecuritySettings {
+ internal ProviderSecuritySettings() : base(true) { }
+
+ // This property is a placeholder for a feature that has not been written yet.
+ /// <summary>
+ /// Gets/sets whether OpenID 1.x relying parties that may not be
+ /// protecting their users from replay attacks are protected from
+ /// replay attacks by this provider.
+ /// </summary>
+ /// <remarks>
+ /// <para>Nonces for protection against replay attacks were not mandated
+ /// by OpenID 1.x, which leaves users open to replay attacks.</para>
+ /// <para>This feature works by preventing associations from being formed
+ /// with OpenID 1.x relying parties, thereby forcing them into
+ /// "dumb" mode and verifying every claim with this provider.
+ /// This gives the provider an opportunity to verify its own nonce
+ /// to protect against replay attacks.</para>
+ /// </remarks>
+ internal bool ProtectDownlevelReplayAttacks { get; set; }
+ }
+}
diff --git a/src/DotNetOpenId/Provider/ProviderSession.cs b/src/DotNetOpenId/Provider/ProviderSession.cs index b524399..bbfd278 100644 --- a/src/DotNetOpenId/Provider/ProviderSession.cs +++ b/src/DotNetOpenId/Provider/ProviderSession.cs @@ -77,8 +77,8 @@ namespace DotNetOpenId.Provider { sessionType = Util.GetRequiredArg(provider.Query, Protocol.openid.session_type);
Debug.Assert(Array.IndexOf(Protocol.Args.SessionType.AllDiffieHellman, sessionType) >= 0, "We should not have been invoked if this wasn't a recognized DH session request.");
- byte[] dh_modulus = Util.GetOptionalBase64Arg(Provider.Query, Protocol.openid.dh_modulus) ?? CryptUtil.DEFAULT_MOD;
- byte[] dh_gen = Util.GetOptionalBase64Arg(Provider.Query, Protocol.openid.dh_gen) ?? CryptUtil.DEFAULT_GEN;
+ byte[] dh_modulus = Util.GetOptionalBase64Arg(Provider.Query, Protocol.openid.dh_modulus) ?? DiffieHellmanUtil.DEFAULT_MOD;
+ byte[] dh_gen = Util.GetOptionalBase64Arg(Provider.Query, Protocol.openid.dh_gen) ?? DiffieHellmanUtil.DEFAULT_GEN;
dh = new DiffieHellmanManaged(dh_modulus, dh_gen, 1024);
consumerPublicKey = Util.GetRequiredBase64Arg(Provider.Query, Protocol.openid.dh_consumer_public);
@@ -89,13 +89,11 @@ namespace DotNetOpenId.Provider { }
public override Dictionary<string, string> Answer(byte[] secret) {
- bool useSha256 = SessionType.Equals(Protocol.Args.SessionType.DH_SHA256, StringComparison.Ordinal);
- byte[] mac_key = CryptUtil.SHAHashXorSecret(
- useSha256 ? (HashAlgorithm) CryptUtil.Sha256 : CryptUtil.Sha1,
+ byte[] mac_key = DiffieHellmanUtil.SHAHashXorSecret(DiffieHellmanUtil.Lookup(Protocol, SessionType),
dh, consumerPublicKey, secret);
var nvc = new Dictionary<string, string>();
- nvc.Add(Protocol.openidnp.dh_server_public, CryptUtil.UnsignedToBase64(dh.CreateKeyExchange()));
+ nvc.Add(Protocol.openidnp.dh_server_public, DiffieHellmanUtil.UnsignedToBase64(dh.CreateKeyExchange()));
nvc.Add(Protocol.openidnp.enc_mac_key, Convert.ToBase64String(mac_key));
return nvc;
diff --git a/src/DotNetOpenId/Provider/Request.cs b/src/DotNetOpenId/Provider/Request.cs index 9257e99..eb3edaf 100644 --- a/src/DotNetOpenId/Provider/Request.cs +++ b/src/DotNetOpenId/Provider/Request.cs @@ -84,10 +84,19 @@ namespace DotNetOpenId.Provider }
/// <summary>
+ /// Gets the version of OpenID being used by the relying party that sent the request.
+ /// </summary>
+ public ProtocolVersion RelyingPartyVersion {
+ get {
+ return Protocol.Lookup(Protocol.Version).ProtocolVersion;
+ }
+ }
+
+ /// <summary>
/// Indicates whether this request has all the information necessary to formulate a response.
/// </summary>
public abstract bool IsResponseReady { get; }
- internal abstract IEncodable CreateResponse();
+ protected abstract IEncodable CreateResponse();
/// <summary>
/// Called whenever a property changes that would cause the response to need to be
/// regenerated if it had already been generated.
@@ -123,9 +132,36 @@ namespace DotNetOpenId.Provider OutgoingExtensions.AddExtensionArguments(extension.TypeUri, extension.Serialize(this));
}
+ /// <summary>
+ /// Attempts to load an extension from an OpenId message.
+ /// </summary>
+ /// <param name="extension">The extension to attempt to load.</param>
+ /// <returns>
+ /// True if the extension was found in the message and successfully loaded.
+ /// False otherwise.
+ /// </returns>
+ bool getExtension(DotNetOpenId.Extensions.IExtensionRequest extension) {
+ var fields = IncomingExtensions.GetExtensionArguments(extension.TypeUri);
+ if (fields != null) {
+ // The extension was found using the preferred TypeUri.
+ return extension.Deserialize(fields, this, extension.TypeUri);
+ } else {
+ // The extension may still be found using secondary TypeUris.
+ if (extension.AdditionalSupportedTypeUris != null) {
+ foreach (string typeUri in extension.AdditionalSupportedTypeUris) {
+ fields = IncomingExtensions.GetExtensionArguments(typeUri);
+ if (fields != null) {
+ // We found one of the older ones.
+ return extension.Deserialize(fields, this, typeUri);
+ }
+ }
+ }
+ }
+ return false;
+ }
public T GetExtension<T>() where T : DotNetOpenId.Extensions.IExtensionRequest, new() {
T extension = new T();
- return extension.Deserialize(IncomingExtensions.GetExtensionArguments(extension.TypeUri), this) ? extension : default(T);
+ return getExtension(extension) ? (T)extension : default(T);
}
public DotNetOpenId.Extensions.IExtensionRequest GetExtension(Type extensionType) {
@@ -135,7 +171,7 @@ namespace DotNetOpenId.Provider Strings.TypeMustImplementX, typeof(DotNetOpenId.Extensions.IExtensionRequest).FullName),
"extensionType");
var extension = (DotNetOpenId.Extensions.IExtensionRequest)Activator.CreateInstance(extensionType);
- return extension.Deserialize(IncomingExtensions.GetExtensionArguments(extension.TypeUri), this) ? extension : null;
+ return getExtension(extension) ? extension : null;
}
public override string ToString() {
diff --git a/src/DotNetOpenId/Provider/Signatory.cs b/src/DotNetOpenId/Provider/Signatory.cs index 32b1945..eaf3d21 100644 --- a/src/DotNetOpenId/Provider/Signatory.cs +++ b/src/DotNetOpenId/Provider/Signatory.cs @@ -41,18 +41,14 @@ namespace DotNetOpenId.Provider { assoc = GetAssociation(assoc_handle, AssociationRelyingPartyType.Smart);
if (assoc == null) {
- if (TraceUtil.Switch.TraceWarning) {
- Trace.TraceWarning("No associaton found with assoc_handle {0}. Setting invalidate_handle and creating new Association.", assoc_handle);
- }
+ Logger.WarnFormat("No associaton found with assoc_handle {0}. Setting invalidate_handle and creating new Association.", assoc_handle);
response.Fields[response.Protocol.openidnp.invalidate_handle] = assoc_handle;
assoc = CreateAssociation(AssociationRelyingPartyType.Dumb, null);
}
} else {
assoc = this.CreateAssociation(AssociationRelyingPartyType.Dumb, null);
- if (TraceUtil.Switch.TraceInfo) {
- Trace.TraceInformation("No assoc_handle supplied. Creating new association.");
- }
+ Logger.Debug("No assoc_handle supplied. Creating new association.");
}
response.Fields[response.Protocol.openidnp.assoc_handle] = assoc.Handle;
@@ -66,15 +62,14 @@ namespace DotNetOpenId.Provider { public virtual bool Verify(string assoc_handle, string signature, IDictionary<string, string> signed_pairs, IList<string> signedKeyOrder) {
Association assoc = GetAssociation(assoc_handle, AssociationRelyingPartyType.Dumb);
if (assoc == null) {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Signature verification failed. No association with handle {0} found ", assoc_handle);
+ Logger.ErrorFormat("Signature verification failed. No association with handle {0} found ", assoc_handle);
return false;
}
string expected_sig = Convert.ToBase64String(assoc.Sign(signed_pairs, signedKeyOrder));
- if (TraceUtil.Switch.TraceError && signature != expected_sig) {
- Trace.TraceError("Expected signature is '{0}'. Actual signature is '{1}' ", expected_sig, signature);
+ if (signature != expected_sig) {
+ Logger.ErrorFormat("Expected signature is '{0}'. Actual signature is '{1}' ", expected_sig, signature);
}
return expected_sig.Equals(signature, StringComparison.Ordinal);
@@ -84,24 +79,25 @@ namespace DotNetOpenId.Provider { if (provider == null && associationType == AssociationRelyingPartyType.Smart)
throw new ArgumentNullException("provider", "For Smart associations, the provider must be given.");
- bool useSha256;
string assoc_type;
+ Protocol associationProtocol;
if (associationType == AssociationRelyingPartyType.Dumb) {
- useSha256 = true;
- assoc_type = Protocol.v20.Args.SignatureAlgorithm.HMAC_SHA256;
+ // We'll just use the best association available.
+ associationProtocol = Protocol.Default;
+ assoc_type = associationProtocol.Args.SignatureAlgorithm.Best;
} else {
+ associationProtocol = provider.Protocol;
assoc_type = Util.GetRequiredArg(provider.Query, provider.Protocol.openid.assoc_type);
Debug.Assert(Array.IndexOf(provider.Protocol.Args.SignatureAlgorithm.All, assoc_type) >= 0, "This should have been checked by our caller.");
- useSha256 = assoc_type.Equals(provider.Protocol.Args.SignatureAlgorithm.HMAC_SHA256, StringComparison.Ordinal);
}
- int hashSize = useSha256 ? CryptUtil.Sha256.HashSize : CryptUtil.Sha1.HashSize;
+ int secretLength = HmacShaAssociation.GetSecretLength(associationProtocol, assoc_type);
RNGCryptoServiceProvider generator = new RNGCryptoServiceProvider();
- byte[] secret = new byte[hashSize / 8];
+ byte[] secret = new byte[secretLength];
byte[] uniq_bytes = new byte[4];
string uniq;
string handle;
- Association assoc;
+ HmacShaAssociation assoc;
generator.GetBytes(secret);
generator.GetBytes(uniq_bytes);
@@ -113,9 +109,7 @@ namespace DotNetOpenId.Provider { handle = "{{" + assoc_type + "}{" + seconds + "}{" + uniq + "}";
TimeSpan lifeSpan = associationType == AssociationRelyingPartyType.Dumb ? dumbSecretLifetime : smartAssociationLifetime;
- assoc = useSha256 ? (Association)
- new HmacSha256Association(handle, secret, lifeSpan) :
- new HmacSha1Association(handle, secret, lifeSpan);
+ assoc = HmacShaAssociation.Create(secretLength, handle, secret, lifeSpan);
store.StoreAssociation(associationType, assoc);
@@ -128,8 +122,7 @@ namespace DotNetOpenId.Provider { Association assoc = store.GetAssociation(associationType, assoc_handle);
if (assoc == null || assoc.IsExpired) {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Association {0} expired or not in store.", assoc_handle);
+ Logger.ErrorFormat("Association {0} expired or not in store.", assoc_handle);
store.RemoveAssociation(associationType, assoc_handle);
assoc = null;
}
@@ -138,8 +131,7 @@ namespace DotNetOpenId.Provider { }
public virtual void Invalidate(string assoc_handle, AssociationRelyingPartyType associationType) {
- if (TraceUtil.Switch.TraceInfo)
- Trace.TraceInformation("Invalidating association '{0}'.", assoc_handle);
+ Logger.DebugFormat("Invalidating association '{0}'.", assoc_handle);
store.RemoveAssociation(associationType, assoc_handle);
}
diff --git a/src/DotNetOpenId/Provider/SigningMessageEncoder.cs b/src/DotNetOpenId/Provider/SigningMessageEncoder.cs index ea5a522..f05f731 100644 --- a/src/DotNetOpenId/Provider/SigningMessageEncoder.cs +++ b/src/DotNetOpenId/Provider/SigningMessageEncoder.cs @@ -16,26 +16,14 @@ namespace DotNetOpenId.Provider { }
public override Response Encode(IEncodable encodable) {
- OnSigning(encodable);
var response = encodable as EncodableResponse;
if (response != null) {
if (response.NeedsSigning) {
- Debug.Assert(!response.Fields.ContainsKey(encodable.Protocol.openidnp.sig));
signatory.Sign(response);
}
}
return base.Encode(encodable);
}
-
- /// <summary>
- /// Used for testing. Allows interception and modification of messages
- /// that are about to be returned to the RP.
- /// </summary>
- public static event EventHandler<EncodeEventArgs> Signing;
- protected virtual void OnSigning(IEncodable encodable) {
- if (Signing != null)
- Signing(this, new EncodeEventArgs(encodable));
- }
}
}
|