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
|
//-----------------------------------------------------------------------
// <copyright file="OAuth2AuthorizationServerChannel.cs" company="Outercurve Foundation">
// Copyright (c) Outercurve Foundation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OAuth2.ChannelElements {
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth2.AuthServer.Messages;
using DotNetOpenAuth.OAuth2.Messages;
using Validation;
/// <summary>
/// The channel for the OAuth protocol.
/// </summary>
internal class OAuth2AuthorizationServerChannel : OAuth2ChannelBase, IOAuth2ChannelWithAuthorizationServer {
/// <summary>
/// The messages receivable by this channel.
/// </summary>
private static readonly Type[] MessageTypes = new Type[] {
typeof(AccessTokenRefreshRequestAS),
typeof(AccessTokenAuthorizationCodeRequestAS),
typeof(AccessTokenResourceOwnerPasswordCredentialsRequest),
typeof(AccessTokenClientCredentialsRequest),
typeof(EndUserAuthorizationRequest),
typeof(EndUserAuthorizationImplicitRequest),
typeof(EndUserAuthorizationFailedResponse),
};
/// <summary>
/// Initializes a new instance of the <see cref="OAuth2AuthorizationServerChannel"/> class.
/// </summary>
/// <param name="authorizationServer">The authorization server.</param>
/// <param name="clientAuthenticationModule">The aggregating client authentication module.</param>
protected internal OAuth2AuthorizationServerChannel(IAuthorizationServerHost authorizationServer, ClientAuthenticationModule clientAuthenticationModule)
: base(MessageTypes, InitializeBindingElements(authorizationServer, clientAuthenticationModule)) {
Requires.NotNull(authorizationServer, "authorizationServer");
this.AuthorizationServer = authorizationServer;
}
/// <summary>
/// Gets the authorization server.
/// </summary>
/// <value>The authorization server.</value>
public IAuthorizationServerHost AuthorizationServer { get; private set; }
/// <summary>
/// Gets or sets the service that checks whether a granted set of scopes satisfies a required set of scopes.
/// </summary>
public IScopeSatisfiedCheck ScopeSatisfiedCheck { get; set; }
/// <summary>
/// Gets the protocol message that may be in the given HTTP response.
/// </summary>
/// <param name="response">The response that is anticipated to contain an protocol message.</param>
/// <returns>
/// The deserialized message parts, if found. Null otherwise.
/// </returns>
/// <exception cref="ProtocolException">Thrown when the response is not valid.</exception>
protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response) {
throw new NotImplementedException();
}
/// <summary>
/// Queues a message for sending in the response stream.
/// </summary>
/// <param name="response">The message to send as a response.</param>
/// <returns>
/// The pending user agent redirect based message to be sent as an HttpResponse.
/// </returns>
/// <remarks>
/// This method implements spec OAuth V1.0 section 5.3.
/// </remarks>
protected override HttpResponseMessage PrepareDirectResponse(IProtocolMessage response) {
var webResponse = new HttpResponseMessage();
ApplyMessageTemplate(response, webResponse);
string json = this.SerializeAsJson(response);
webResponse.Content = new StringContent(json, Encoding.UTF8, JsonEncoded);
return webResponse;
}
/// <summary>
/// Gets the protocol message that may be embedded in the given HTTP request.
/// </summary>
/// <param name="request">The request to search for an embedded message.</param>
/// <returns>
/// The deserialized message, if one is found. Null otherwise.
/// </returns>
protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestBase request, CancellationToken cancellationToken) {
if (!string.IsNullOrEmpty(request.Url.Fragment)) {
var fields = HttpUtility.ParseQueryString(request.Url.Fragment.Substring(1)).ToDictionary();
MessageReceivingEndpoint recipient;
try {
recipient = request.GetRecipient();
} catch (ArgumentException ex) {
Logger.Messaging.WarnFormat("Unrecognized HTTP request: " + ex.ToString());
return null;
}
return (IDirectedProtocolMessage)this.Receive(fields, recipient);
}
return base.ReadFromRequestCore(request, cancellationToken);
}
/// <summary>
/// Initializes the binding elements for the OAuth channel.
/// </summary>
/// <param name="authorizationServer">The authorization server.</param>
/// <param name="clientAuthenticationModule">The aggregating client authentication module.</param>
/// <returns>
/// An array of binding elements used to initialize the channel.
/// </returns>
private static IChannelBindingElement[] InitializeBindingElements(IAuthorizationServerHost authorizationServer, ClientAuthenticationModule clientAuthenticationModule) {
Requires.NotNull(authorizationServer, "authorizationServer");
Requires.NotNull(clientAuthenticationModule, "clientAuthenticationModule");
var bindingElements = new List<IChannelBindingElement>();
// The order they are provided is used for outgoing messgaes, and reversed for incoming messages.
bindingElements.Add(new MessageValidationBindingElement(clientAuthenticationModule));
bindingElements.Add(new TokenCodeSerializationBindingElement());
return bindingElements.ToArray();
}
}
}
|