From aae0d6c14ae6a473f3651feb1e6e3aeea8b3fe16 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sat, 24 Jan 2009 22:18:05 -0800 Subject: [PATCH] Ported OpenID relying party COM server component from DotNetOpenId. --- src/DotNetOpenAuth/DotNetOpenAuth.csproj | 2 + .../OpenId/Interop/AuthenticationResponseShim.cs | 101 +++++++++++++++++ .../OpenId/Interop/OpenIdRelyingPartyShim.cs | 121 +++++++++++++++++++++ 3 files changed, 224 insertions(+) create mode 100644 src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs create mode 100644 src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index be0ce0a..fa2b65e 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -212,6 +212,8 @@ + + diff --git a/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs b/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs new file mode 100644 index 0000000..4db26c9 --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Andrew Arnott. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Interop { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Runtime.InteropServices; + using System.Web; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// + /// The COM type used to provide details of an authentication result to a relying party COM client. + /// + [Obsolete("This class acts as a COM Server and should not be called directly from .NET code.")] + public class AuthenticationResponseShim { + /// + /// The response read in by the Relying Party. + /// + private readonly IAuthenticationResponse response; + + /// + /// Initializes a new instance of the class. + /// + /// The response. + internal AuthenticationResponseShim(IAuthenticationResponse response) { + ErrorUtilities.VerifyArgumentNotNull(response, "response"); + + this.response = response; + } + + /// + /// Gets an Identifier that the end user claims to own. For use with user database storage and lookup. + /// May be null for some failed authentications (i.e. failed directed identity authentications). + /// + /// + /// + /// This is the secure identifier that should be used for database storage and lookup. + /// It is not always friendly (i.e. =Arnott becomes =!9B72.7DD1.50A9.5CCD), but it protects + /// user identities against spoofing and other attacks. + /// + /// + /// For user-friendly identifiers to display, use the + /// property. + /// + /// + public string ClaimedIdentifier { + get { return this.response.ClaimedIdentifier; } + } + + /// + /// Gets a user-friendly OpenID Identifier for display purposes ONLY. + /// + /// + /// + /// This should be put through before + /// sending to a browser to secure against javascript injection attacks. + /// + /// + /// This property retains some aspects of the user-supplied identifier that get lost + /// in the . For example, XRIs used as user-supplied + /// identifiers (i.e. =Arnott) become unfriendly unique strings (i.e. =!9B72.7DD1.50A9.5CCD). + /// For display purposes, such as text on a web page that says "You're logged in as ...", + /// this property serves to provide the =Arnott string, or whatever else is the most friendly + /// string close to what the user originally typed in. + /// + /// + /// If the user-supplied identifier is a URI, this property will be the URI after all + /// redirects, and with the protocol and fragment trimmed off. + /// If the user-supplied identifier is an XRI, this property will be the original XRI. + /// If the user-supplied identifier is an OpenID Provider identifier (i.e. yahoo.com), + /// this property will be the Claimed Identifier, with the protocol stripped if it is a URI. + /// + /// + /// It is very important that this property never be used for database storage + /// or lookup to avoid identity spoofing and other security risks. For database storage + /// and lookup please use the property. + /// + /// + public string FriendlyIdentifierForDisplay { + get { return this.response.FriendlyIdentifierForDisplay; } + } + + /// + /// Gets a value indicating whether the authentication attempt succeeded. + /// + public bool Successful { + get { return this.response.Status == AuthenticationStatus.Authenticated; } + } + + /// + /// Gets details regarding a failed authentication attempt, if available. + /// + public string ExceptionMessage { + get { return this.response.Exception != null ? this.response.Exception.Message : null; } + } + } +} diff --git a/src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs b/src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs new file mode 100644 index 0000000..51feb69 --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/Interop/OpenIdRelyingPartyShim.cs @@ -0,0 +1,121 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Andrew Arnott. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Interop { + using System; + using System.Diagnostics.CodeAnalysis; + using System.IO; + using System.Runtime.InteropServices; + using System.Text; + using System.Web; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.RelyingParty; + + /// + /// The COM interface describing the DotNetOpenId functionality available to + /// COM client relying parties. + /// + [Guid("00462F34-21BE-456c-B986-B6DDE4DC5CA8")] + [InterfaceType(ComInterfaceType.InterfaceIsDual)] + public interface IOpenIdRelyingParty { + /// + /// Creates an authentication request to verify that a user controls + /// some given Identifier. + /// + /// + /// The Identifier supplied by the user. This may be a URL, an XRI or i-name. + /// + /// + /// The shorest URL that describes this relying party web site's address. + /// For example, if your login page is found at https://www.example.com/login.aspx, + /// your realm would typically be https://www.example.com/. + /// + /// + /// The URL of the login page, or the page prepared to receive authentication + /// responses from the OpenID Provider. + /// + /// + /// An authentication request object that describes the HTTP response to + /// send to the user agent to initiate the authentication. + /// + /// Thrown if no OpenID endpoint could be found. + string CreateRequest(string userSuppliedIdentifier, string realm, string returnToUrl); + + /// + /// Gets the result of a user agent's visit to his OpenId provider in an + /// authentication attempt. Null if no response is available. + /// + /// The incoming request URL . + /// The form data that may have been included in the case of a POST request. + /// The Provider's response to a previous authentication request, or null if no response is present. +#pragma warning disable 0618 // we're using the COM type properly + AuthenticationResponseShim ProcessAuthentication(string url, string form); +#pragma warning restore 0618 + } + + /// + /// Implementation of , providing a subset of the + /// functionality available to .NET clients. + /// + [Guid("4D6FB236-1D66-4311-B761-972C12BB85E8")] + [ProgId("DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty")] + [ComVisible(true), Obsolete("This class acts as a COM Server and should not be called directly from .NET code.", true)] + [ClassInterface(ClassInterfaceType.None)] + [ComSourceInterfaces(typeof(IOpenIdRelyingParty))] + public class OpenIdRelyingPartyShim : IOpenIdRelyingParty { + /// + /// Creates an authentication request to verify that a user controls + /// some given Identifier. + /// + /// + /// The Identifier supplied by the user. This may be a URL, an XRI or i-name. + /// + /// + /// The shorest URL that describes this relying party web site's address. + /// For example, if your login page is found at https://www.example.com/login.aspx, + /// your realm would typically be https://www.example.com/. + /// + /// + /// The URL of the login page, or the page prepared to receive authentication + /// responses from the OpenID Provider. + /// + /// + /// An authentication request object that describes the HTTP response to + /// send to the user agent to initiate the authentication. + /// + /// Thrown if no OpenID endpoint could be found. + [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "COM requires primitive types")] + public string CreateRequest(string userSuppliedIdentifier, string realm, string returnToUrl) { + OpenIdRelyingParty rp = new OpenIdRelyingParty(null); + UserAgentResponse response = rp.CreateRequest(userSuppliedIdentifier, realm, new Uri(returnToUrl)).RedirectingResponse; + return response.DirectUriRequest.AbsoluteUri; + } + + /// + /// Gets the result of a user agent's visit to his OpenId provider in an + /// authentication attempt. Null if no response is available. + /// + /// The incoming request URL. + /// The form data that may have been included in the case of a POST request. + /// The Provider's response to a previous authentication request, or null if no response is present. + public AuthenticationResponseShim ProcessAuthentication(string url, string form) { + Uri uri = new Uri(url); + OpenIdRelyingParty rp = new OpenIdRelyingParty(null); + HttpRequestInfo requestInfo = new HttpRequestInfo { Url = new Uri(url) }; + if (form != null) { + requestInfo.HttpMethod = "POST"; + requestInfo.InputStream = new MemoryStream(Encoding.Unicode.GetBytes(form)); + } + + var response = rp.GetResponse(requestInfo); + if (response != null) { + return new AuthenticationResponseShim(response); + } + + return null; + } + } +} -- 2.11.4.GIT