summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/Interop/OpenIdRelyingPartyShim.cs
blob: 97b3780b6cf719e89b1158334bf62b3413b18d13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
//-----------------------------------------------------------------------
// <copyright file="OpenIdRelyingPartyShim.cs" company="Outercurve Foundation">
//     Copyright (c) Outercurve Foundation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

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.Extensions.SimpleRegistration;
	using DotNetOpenAuth.OpenId.RelyingParty;

	/// <summary>
	/// The COM interface describing the DotNetOpenAuth functionality available to
	/// COM client OpenID relying parties.
	/// </summary>
	[Guid("56BD3DB0-EE0D-4191-ADFC-1F3705CD2636")]
	[InterfaceType(ComInterfaceType.InterfaceIsDual)]
	public interface IOpenIdRelyingParty {
		/// <summary>
		/// Creates an authentication request to verify that a user controls
		/// some given Identifier.
		/// </summary>
		/// <param name="userSuppliedIdentifier">
		/// The Identifier supplied by the user.  This may be a URL, an XRI or i-name.
		/// </param>
		/// <param name="realm">
		/// 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/.
		/// </param>
		/// <param name="returnToUrl">
		/// The URL of the login page, or the page prepared to receive authentication 
		/// responses from the OpenID Provider.
		/// </param>
		/// <returns>
		/// An authentication request object that describes the HTTP response to
		/// send to the user agent to initiate the authentication.
		/// </returns>
		/// <exception cref="ProtocolException">Thrown if no OpenID endpoint could be found.</exception>
		string CreateRequest(string userSuppliedIdentifier, string realm, string returnToUrl);

		/// <summary>
		/// Creates an authentication request to verify that a user controls
		/// some given Identifier.
		/// </summary>
		/// <param name="userSuppliedIdentifier">The Identifier supplied by the user.  This may be a URL, an XRI or i-name.</param>
		/// <param name="realm">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/.</param>
		/// <param name="returnToUrl">The URL of the login page, or the page prepared to receive authentication
		/// responses from the OpenID Provider.</param>
		/// <param name="optionalSreg">A comma-delimited list of simple registration fields to request as optional.</param>
		/// <param name="requiredSreg">A comma-delimited list of simple registration fields to request as required.</param>
		/// <returns>
		/// An authentication request object that describes the HTTP response to
		/// send to the user agent to initiate the authentication.
		/// </returns>
		/// <exception cref="ProtocolException">Thrown if no OpenID endpoint could be found.</exception>
		[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Accepted acronym")]
		string CreateRequestWithSimpleRegistration(string userSuppliedIdentifier, string realm, string returnToUrl, string optionalSreg, string requiredSreg);

		/// <summary>
		/// Gets the result of a user agent's visit to his OpenId provider in an
		/// authentication attempt.  Null if no response is available.
		/// </summary>
		/// <param name="url">The incoming request URL .</param>
		/// <param name="form">The form data that may have been included in the case of a POST request.</param>
		/// <returns>The Provider's response to a previous authentication request, or null if no response is present.</returns>
#pragma warning disable 0618 // we're using the COM type properly
		AuthenticationResponseShim ProcessAuthentication(string url, string form);
#pragma warning restore 0618
	}

	/// <summary>
	/// Implementation of <see cref="IOpenIdRelyingParty"/>, providing a subset of the
	/// functionality available to .NET clients.
	/// </summary>
	[Guid("8F97A798-B4C5-4da5-9727-EE7DD96A8CD9")]
	[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)]
	public sealed class OpenIdRelyingPartyShim : IOpenIdRelyingParty {
		/// <summary>
		/// The OpenIdRelyingParty instance to use for requests.
		/// </summary>
		private static OpenIdRelyingParty relyingParty;

		/// <summary>
		/// Initializes static members of the <see cref="OpenIdRelyingPartyShim"/> class.
		/// </summary>
		static OpenIdRelyingPartyShim() {
			relyingParty = new OpenIdRelyingParty(null);
			relyingParty.Behaviors.Add(new RelyingParty.Behaviors.AXFetchAsSregTransform());
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="OpenIdRelyingPartyShim"/> class.
		/// </summary>
		public OpenIdRelyingPartyShim() {
			Reporting.RecordFeatureUse(this);
		}

		/// <summary>
		/// Creates an authentication request to verify that a user controls
		/// some given Identifier.
		/// </summary>
		/// <param name="userSuppliedIdentifier">
		/// The Identifier supplied by the user.  This may be a URL, an XRI or i-name.
		/// </param>
		/// <param name="realm">
		/// 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/.
		/// </param>
		/// <param name="returnToUrl">
		/// The URL of the login page, or the page prepared to receive authentication 
		/// responses from the OpenID Provider.
		/// </param>
		/// <returns>
		/// An authentication request object that describes the HTTP response to
		/// send to the user agent to initiate the authentication.
		/// </returns>
		/// <exception cref="ProtocolException">Thrown if no OpenID endpoint could be found.</exception>
		[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "COM requires primitive types")]
		public string CreateRequest(string userSuppliedIdentifier, string realm, string returnToUrl) {
			var request = relyingParty.CreateRequest(userSuppliedIdentifier, realm, new Uri(returnToUrl));
			return request.RedirectingResponse.GetDirectUriRequest(relyingParty.Channel).AbsoluteUri;
		}

		/// <summary>
		/// Creates an authentication request to verify that a user controls
		/// some given Identifier.
		/// </summary>
		/// <param name="userSuppliedIdentifier">The Identifier supplied by the user.  This may be a URL, an XRI or i-name.</param>
		/// <param name="realm">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/.</param>
		/// <param name="returnToUrl">The URL of the login page, or the page prepared to receive authentication
		/// responses from the OpenID Provider.</param>
		/// <param name="optionalSreg">A comma-delimited list of simple registration fields to request as optional.</param>
		/// <param name="requiredSreg">A comma-delimited list of simple registration fields to request as required.</param>
		/// <returns>
		/// An authentication request object that describes the HTTP response to
		/// send to the user agent to initiate the authentication.
		/// </returns>
		/// <exception cref="ProtocolException">Thrown if no OpenID endpoint could be found.</exception>
		[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "COM requires primitive types")]
		public string CreateRequestWithSimpleRegistration(string userSuppliedIdentifier, string realm, string returnToUrl, string optionalSreg, string requiredSreg) {
			var request = relyingParty.CreateRequest(userSuppliedIdentifier, realm, new Uri(returnToUrl));

			ClaimsRequest sreg = new ClaimsRequest();
			if (!string.IsNullOrEmpty(optionalSreg)) {
				sreg.SetProfileRequestFromList(optionalSreg.Split(','), DemandLevel.Request);
			}
			if (!string.IsNullOrEmpty(requiredSreg)) {
				sreg.SetProfileRequestFromList(requiredSreg.Split(','), DemandLevel.Require);
			}
			request.AddExtension(sreg);
			return request.RedirectingResponse.GetDirectUriRequest(relyingParty.Channel).AbsoluteUri;
		}

		/// <summary>
		/// Gets the result of a user agent's visit to his OpenId provider in an
		/// authentication attempt.  Null if no response is available.
		/// </summary>
		/// <param name="url">The incoming request URL.</param>
		/// <param name="form">The form data that may have been included in the case of a POST request.</param>
		/// <returns>The Provider's response to a previous authentication request, or null if no response is present.</returns>
		public AuthenticationResponseShim ProcessAuthentication(string url, string form) {
			HttpRequestInfo requestInfo = new HttpRequestInfo { UrlBeforeRewriting = new Uri(url) };
			if (!string.IsNullOrEmpty(form)) {
				requestInfo.HttpMethod = "POST";
				requestInfo.InputStream = new MemoryStream(Encoding.Unicode.GetBytes(form));
			}

			var response = relyingParty.GetResponse(requestInfo);
			if (response != null) {
				return new AuthenticationResponseShim(response);
			}

			return null;
		}
	}
}