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
|
//-----------------------------------------------------------------------
// <copyright file="OpenIdClient.cs" company="Microsoft">
// Copyright (c) Microsoft. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.AspNet.Clients {
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Web;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;
/// <summary>
/// Base classes for OpenID clients.
/// </summary>
public class OpenIdClient : IAuthenticationClient {
#region Constants and Fields
/// <summary>
/// The _openid relaying party.
/// </summary>
private static readonly OpenIdRelyingParty RelyingParty =
new OpenIdRelyingParty(new StandardRelyingPartyApplicationStore());
/// <summary>
/// The _provider identifier.
/// </summary>
private readonly Identifier providerIdentifier;
/// <summary>
/// The _provider name.
/// </summary>
private readonly string providerName;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="OpenIdClient"/> class.
/// </summary>
/// <param name="providerName">
/// Name of the provider.
/// </param>
/// <param name="providerIdentifier">
/// The provider identifier, which is the usually the login url of the specified provider.
/// </param>
public OpenIdClient(string providerName, Identifier providerIdentifier) {
Requires.NotNullOrEmpty(providerName, "providerName");
Requires.NotNull(providerIdentifier, "providerIdentifier");
this.providerName = providerName;
this.providerIdentifier = providerIdentifier;
}
#endregion
#region Public Properties
/// <summary>
/// Gets the name of the provider which provides authentication service.
/// </summary>
public string ProviderName {
get {
return this.providerName;
}
}
#endregion
#region Public Methods and Operators
/// <summary>
/// Attempts to authenticate users by forwarding them to an external website, and upon succcess or failure, redirect users back to the specified url.
/// </summary>
/// <param name="context">
/// The context of the current request.
/// </param>
/// <param name="returnUrl">
/// The return url after users have completed authenticating against external website.
/// </param>
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings",
Justification = "We don't have a Uri object handy.")]
public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) {
Requires.NotNull(returnUrl, "returnUrl");
var realm = new Realm(returnUrl.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped));
IAuthenticationRequest request = RelyingParty.CreateRequest(this.providerIdentifier, realm, returnUrl);
// give subclasses a chance to modify request message, e.g. add extension attributes, etc.
this.OnBeforeSendingAuthenticationRequest(request);
request.RedirectToProvider();
}
/// <summary>
/// Check if authentication succeeded after user is redirected back from the service provider.
/// </summary>
/// <param name="context">
/// The context of the current request.
/// </param>
/// <returns>
/// An instance of <see cref="AuthenticationResult"/> containing authentication result.
/// </returns>
public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) {
IAuthenticationResponse response = RelyingParty.GetResponse();
if (response == null) {
throw new InvalidOperationException(WebResources.OpenIDFailedToGetResponse);
}
if (response.Status == AuthenticationStatus.Authenticated) {
string id = response.ClaimedIdentifier;
string username;
Dictionary<string, string> extraData = this.GetExtraData(response) ?? new Dictionary<string, string>();
// try to look up username from the 'username' or 'email' property. If not found, fall back to 'friendly id'
if (!extraData.TryGetValue("username", out username) && !extraData.TryGetValue("email", out username)) {
username = response.FriendlyIdentifierForDisplay;
}
return new AuthenticationResult(true, this.ProviderName, id, username, extraData);
}
return AuthenticationResult.Failed;
}
#endregion
#region Methods
/// <summary>
/// Gets the extra data obtained from the response message when authentication is successful.
/// </summary>
/// <param name="response">
/// The response message.
/// </param>
/// <returns>Always null.</returns>
protected virtual Dictionary<string, string> GetExtraData(IAuthenticationResponse response) {
return null;
}
/// <summary>
/// Called just before the authentication request is sent to service provider.
/// </summary>
/// <param name="request">
/// The request.
/// </param>
protected virtual void OnBeforeSendingAuthenticationRequest(IAuthenticationRequest request) { }
#endregion
}
}
|