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

namespace WebFormsRelyingParty.Code {
	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 WebFormsRelyingParty.Consumer PendingAuthorizationConsumer {
			get {
				ITokenContainingMessage message = PendingAuthorizationRequest;
				if (message == null) {
					throw new InvalidOperationException();
				}

				return Global.DataContext.IssuedToken.OfType<IssuedRequestToken>().First(t => t.Token == message.Token).Consumer;
			}
		}

		public static void AuthorizePendingRequestToken() {
			var pendingRequest = PendingAuthorizationRequest;
			if (pendingRequest == null) {
				throw new InvalidOperationException("No pending authorization request to authorize.");
			}

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

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

		/// <summary>
		/// Initializes the <see cref="serviceProvider"/> field if it has not yet been initialized.
		/// </summary>
		private static void EnsureInitialized() {
			if (serviceProvider == 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 = postEndpoint,
							AccessTokenEndpoint = postEndpoint,
							UserAuthorizationEndpoint = getEndpoint,
						};
					}

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

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