summaryrefslogtreecommitdiffstats
path: root/projecttemplates/RelyingPartyLogic/OAuthServiceProvider.cs
blob: 357464a4709d9134f522f188ea1f638b6dbeb9b3 (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
//-----------------------------------------------------------------------
// <copyright file="OAuthServiceProvider.cs" company="Andrew Arnott">
//     Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace RelyingPartyLogic {
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Web;
	using DotNetOpenAuth.Messaging;
	using DotNetOpenAuth.OAuth;
	using DotNetOpenAuth.OAuth.ChannelElements;
	using DotNetOpenAuth.OAuth.Messages;

	public class OAuthServiceProvider {
		private const string PendingAuthorizationRequestSessionKey = "PendingAuthorizationRequest";

		/// <summary>
		/// The shared service description for this web site.
		/// </summary>
		private static ServiceProviderDescription serviceDescription;

		private static OAuthServiceProviderTokenManager tokenManager;

		/// <summary>
		/// The shared service provider object.
		/// </summary>
		private static ServiceProvider serviceProvider;

		/// <summary>
		/// The lock to synchronize initialization of the <see cref="serviceProvider"/> field.
		/// </summary>
		private static object initializerLock = new object();

		/// <summary>
		/// Gets the service provider.
		/// </summary>
		/// <value>The service provider.</value>
		public static ServiceProvider ServiceProvider {
			get {
				EnsureInitialized();
				return serviceProvider;
			}
		}

		/// <summary>
		/// Gets the service description.
		/// </summary>
		/// <value>The service description.</value>
		public static ServiceProviderDescription ServiceDescription {
			get {
				EnsureInitialized();
				return serviceDescription;
			}
		}

		public static UserAuthorizationRequest PendingAuthorizationRequest {
			get { return HttpContext.Current.Session[PendingAuthorizationRequestSessionKey] as UserAuthorizationRequest; }
			set { HttpContext.Current.Session[PendingAuthorizationRequestSessionKey] = value; }
		}

		public static Consumer PendingAuthorizationConsumer {
			get {
				ITokenContainingMessage message = PendingAuthorizationRequest;
				if (message == null) {
					throw new InvalidOperationException();
				}

				return Database.DataContext.IssuedTokens.OfType<IssuedRequestToken>().Include("Consumer").First(t => t.Token == message.Token).Consumer;
			}
		}

		public static void AuthorizePendingRequestToken() {
			var response = AuthorizePendingRequestTokenAndGetResponse();
			if (response != null) {
				serviceProvider.Channel.Send(response);
			}
		}

		public static OutgoingWebResponse AuthorizePendingRequestTokenAsWebResponse() {
			var response = AuthorizePendingRequestTokenAndGetResponse();
			if (response != null) {
				return serviceProvider.Channel.PrepareResponse(response);
			} else {
				return null;
			}
		}

		private static UserAuthorizationResponse AuthorizePendingRequestTokenAndGetResponse() {
			var pendingRequest = PendingAuthorizationRequest;
			if (pendingRequest == null) {
				throw new InvalidOperationException("No pending authorization request to authorize.");
			}

			ITokenContainingMessage msg = pendingRequest;
			var token = Database.DataContext.IssuedTokens.OfType<IssuedRequestToken>().First(t => t.Token == msg.Token);
			token.Authorize();

			PendingAuthorizationRequest = null;
			var response = serviceProvider.PrepareAuthorizationResponse(pendingRequest);
			return response;
		}

		/// <summary>
		/// Initializes the <see cref="serviceProvider"/> field if it has not yet been initialized.
		/// </summary>
		private static void EnsureInitialized() {
			if (serviceProvider == null || serviceDescription == null) {
				lock (initializerLock) {
					if (serviceDescription == null) {
						//var postEndpoint = new MessageReceivingEndpoint(new Uri(Utilities.ApplicationRoot, "OAuth.ashx"), HttpDeliveryMethods.PostRequest);
						//var getEndpoint = new MessageReceivingEndpoint(postEndpoint.Location, HttpDeliveryMethods.GetRequest);

						serviceDescription = new ServiceProviderDescription {
							TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
							RequestTokenEndpoint = _requestTokenEndpoint,
							AccessTokenEndpoint = _accessTokenEndpoint,
							UserAuthorizationEndpoint = _userAuthorizationEndpoint,
						};

						if (tokenManager == null) {
							tokenManager = new OAuthServiceProviderTokenManager();
						}
						serviceProvider = new ServiceProvider(serviceDescription, tokenManager);
					}

					if (tokenManager == null) {
						tokenManager = new OAuthServiceProviderTokenManager();
					}

					if (serviceProvider == null) {
						serviceProvider = new ServiceProvider(serviceDescription, tokenManager);
					}
				}
			}
		}

		private static MessageReceivingEndpoint _requestTokenEndpoint;
		private static MessageReceivingEndpoint _accessTokenEndpoint;
		private static MessageReceivingEndpoint _userAuthorizationEndpoint;

		public static MessageReceivingEndpoint RequestTokenEndpoint {
			get {
				return _requestTokenEndpoint;
			}
			set {
				_requestTokenEndpoint = value;
				serviceDescription = null;
			}
		}

		public static MessageReceivingEndpoint AccessTokenEndpoint {
			get {
				return _accessTokenEndpoint;
			}
			set {
				_accessTokenEndpoint = value;
				serviceDescription = null;
			}
		}

		public static MessageReceivingEndpoint UserAuthorizationEndpoint {
			get {
				return _userAuthorizationEndpoint;
			}
			set {
				_userAuthorizationEndpoint = value;
				serviceDescription = null;
			}
		}
	}
}