summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OAuth2
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.OAuth2')
-rw-r--r--src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj16
-rw-r--r--src/DotNetOpenAuth.OAuth2/OAuth2/AuthorizationServer.cs258
-rw-r--r--src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.Designer.cs56
-rw-r--r--src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.cs192
-rw-r--r--src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.resx120
-rw-r--r--src/DotNetOpenAuth.OAuth2/OAuth2/ClientBase.cs256
-rw-r--r--src/DotNetOpenAuth.OAuth2/OAuth2/ResourceServer.cs136
-rw-r--r--src/DotNetOpenAuth.OAuth2/OAuth2/UserAgentClient.cs123
-rw-r--r--src/DotNetOpenAuth.OAuth2/OAuth2/WebServerClient.cs130
-rw-r--r--src/DotNetOpenAuth.OAuth2/Properties/AssemblyInfo.cs6
10 files changed, 6 insertions, 1287 deletions
diff --git a/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj b/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj
index d1a2d3c..59c29aa 100644
--- a/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj
+++ b/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj
@@ -36,12 +36,6 @@
<Compile Include="OAuth2\ChannelElements\AuthorizationCode.cs" />
<Compile Include="OAuth2\ChannelElements\AuthorizationCodeBindingElement.cs" />
<Compile Include="OAuth2\ChannelElements\AuthServerAllFlowsBindingElement.cs" />
- <Compile Include="OAuth2\ClientAuthorizationView.cs">
- <SubType>UserControl</SubType>
- </Compile>
- <Compile Include="OAuth2\ClientAuthorizationView.Designer.cs">
- <DependentUpon>ClientAuthorizationView.cs</DependentUpon>
- </Compile>
<Compile Include="OAuth2\IAccessTokenAnalyzer.cs" />
<Compile Include="OAuth2\IAuthorizationServer.cs" />
<Compile Include="OAuth2\IAuthorizationState.cs" />
@@ -66,14 +60,10 @@
<Compile Include="OAuth2\Messages\AccessTokenFailedResponse.cs" />
<Compile Include="OAuth2\Messages\AccessTokenSuccessResponse.cs" />
<Compile Include="OAuth2\Messages\EndUserAuthorizationSuccessResponseBase.cs" />
- <Compile Include="OAuth2\ResourceServer.cs" />
<Compile Include="OAuth2\StandardAccessTokenAnalyzer.cs" />
- <Compile Include="OAuth2\UserAgentClient.cs" />
- <Compile Include="OAuth2\AuthorizationServer.cs" />
<Compile Include="OAuth2\OAuthUtilities.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="OAuth2\ChannelElements\OAuth2AuthorizationServerChannel.cs" />
- <Compile Include="OAuth2\ClientBase.cs" />
<Compile Include="OAuth2\Messages\MessageBase.cs" />
<Compile Include="OAuth2\Messages\EndUserAuthorizationRequest.cs" />
<Compile Include="OAuth2\Protocol.cs" />
@@ -83,18 +73,12 @@
<DependentUpon>OAuthStrings.resx</DependentUpon>
</Compile>
<Compile Include="OAuth2\AuthorizationServerDescription.cs" />
- <Compile Include="OAuth2\WebServerClient.cs" />
</ItemGroup>
<ItemGroup>
<None Include="OAuth2\Messages\OAuth 2 Messages.cd" />
<None Include="OAuth2\OAuth 2 client facades.cd" />
</ItemGroup>
<ItemGroup>
- <EmbeddedResource Include="OAuth2\ClientAuthorizationView.resx">
- <DependentUpon>ClientAuthorizationView.cs</DependentUpon>
- </EmbeddedResource>
- </ItemGroup>
- <ItemGroup>
<EmbeddedResource Include="OAuth2\OAuthStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>OAuthStrings.Designer.cs</LastGenOutput>
diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/AuthorizationServer.cs
deleted file mode 100644
index ad40fa5..0000000
--- a/src/DotNetOpenAuth.OAuth2/OAuth2/AuthorizationServer.cs
+++ /dev/null
@@ -1,258 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="AuthorizationServer.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth2 {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Security.Cryptography;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth2.ChannelElements;
- using DotNetOpenAuth.OAuth2.Messages;
-
- /// <summary>
- /// Authorization Server supporting the web server flow.
- /// </summary>
- public class AuthorizationServer {
- /// <summary>
- /// Initializes a new instance of the <see cref="AuthorizationServer"/> class.
- /// </summary>
- /// <param name="authorizationServer">The authorization server.</param>
- public AuthorizationServer(IAuthorizationServer authorizationServer) {
- Contract.Requires<ArgumentNullException>(authorizationServer != null);
- this.OAuthChannel = new OAuth2AuthorizationServerChannel(authorizationServer);
- }
-
- /// <summary>
- /// Gets the channel.
- /// </summary>
- /// <value>The channel.</value>
- public Channel Channel {
- get { return this.OAuthChannel; }
- }
-
- /// <summary>
- /// Gets the authorization server.
- /// </summary>
- /// <value>The authorization server.</value>
- public IAuthorizationServer AuthorizationServerServices {
- get { return this.OAuthChannel.AuthorizationServer; }
- }
-
- /// <summary>
- /// Gets the channel.
- /// </summary>
- internal OAuth2AuthorizationServerChannel OAuthChannel { get; private set; }
-
- /// <summary>
- /// Reads in a client's request for the Authorization Server to obtain permission from
- /// the user to authorize the Client's access of some protected resource(s).
- /// </summary>
- /// <param name="request">The HTTP request to read from.</param>
- /// <returns>The incoming request, or null if no OAuth message was attached.</returns>
- /// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
- public EndUserAuthorizationRequest ReadAuthorizationRequest(HttpRequestInfo request = null) {
- if (request == null) {
- request = this.Channel.GetRequestFromContext();
- }
-
- EndUserAuthorizationRequest message;
- if (this.Channel.TryReadFromRequest(request, out message)) {
- if (message.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) {
- // Clients with no secrets can only request implicit grant types.
- var client = this.AuthorizationServerServices.GetClientOrThrow(message.ClientIdentifier);
- ErrorUtilities.VerifyProtocol(!String.IsNullOrEmpty(client.Secret), Protocol.unauthorized_client);
- }
- }
-
- return message;
- }
-
- /// <summary>
- /// Approves an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
- /// </summary>
- /// <param name="authorizationRequest">The authorization request to approve.</param>
- /// <param name="userName">The username of the account that approved the request (or whose data will be accessed by the client).</param>
- /// <param name="scopes">The scope of access the client should be granted. If <c>null</c>, all scopes in the original request will be granted.</param>
- /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
- public void ApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string userName, IEnumerable<string> scopes = null, Uri callback = null) {
- Contract.Requires<ArgumentNullException>(authorizationRequest != null);
-
- var response = this.PrepareApproveAuthorizationRequest(authorizationRequest, userName, scopes, callback);
- this.Channel.Respond(response);
- }
-
- /// <summary>
- /// Rejects an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
- /// </summary>
- /// <param name="authorizationRequest">The authorization request to disapprove.</param>
- /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
- public void RejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) {
- Contract.Requires<ArgumentNullException>(authorizationRequest != null);
-
- var response = this.PrepareRejectAuthorizationRequest(authorizationRequest, callback);
- this.Channel.Respond(response);
- }
-
- /// <summary>
- /// Checks the incoming HTTP request for an access token request and prepares a response if the request message was found.
- /// </summary>
- /// <param name="response">The formulated response, or <c>null</c> if the request was not found..</param>
- /// <returns>A value indicating whether any access token request was found in the HTTP request.</returns>
- /// <remarks>
- /// This method assumes that the authorization server and the resource server are the same and that they share a single
- /// asymmetric key for signing and encrypting the access token. If this is not true, use the <see cref="ReadAccessTokenRequest"/> method instead.
- /// </remarks>
- public bool TryPrepareAccessTokenResponse(out IDirectResponseProtocolMessage response) {
- return this.TryPrepareAccessTokenResponse(this.Channel.GetRequestFromContext(), out response);
- }
-
- /// <summary>
- /// Checks the incoming HTTP request for an access token request and prepares a response if the request message was found.
- /// </summary>
- /// <param name="httpRequestInfo">The HTTP request info.</param>
- /// <param name="response">The formulated response, or <c>null</c> if the request was not found..</param>
- /// <returns>A value indicating whether any access token request was found in the HTTP request.</returns>
- /// <remarks>
- /// This method assumes that the authorization server and the resource server are the same and that they share a single
- /// asymmetric key for signing and encrypting the access token. If this is not true, use the <see cref="ReadAccessTokenRequest"/> method instead.
- /// </remarks>
- public bool TryPrepareAccessTokenResponse(HttpRequestInfo httpRequestInfo, out IDirectResponseProtocolMessage response) {
- Contract.Requires<ArgumentNullException>(httpRequestInfo != null);
- Contract.Ensures(Contract.Result<bool>() == (Contract.ValueAtReturn<IDirectResponseProtocolMessage>(out response) != null));
-
- var request = this.ReadAccessTokenRequest(httpRequestInfo);
- if (request != null) {
- response = this.PrepareAccessTokenResponse(request);
- return true;
- }
-
- response = null;
- return false;
- }
-
- /// <summary>
- /// Reads the access token request.
- /// </summary>
- /// <param name="requestInfo">The request info.</param>
- /// <returns>The Client's request for an access token; or <c>null</c> if no such message was found in the request.</returns>
- public AccessTokenRequestBase ReadAccessTokenRequest(HttpRequestInfo requestInfo = null) {
- if (requestInfo == null) {
- requestInfo = this.Channel.GetRequestFromContext();
- }
-
- AccessTokenRequestBase request;
- this.Channel.TryReadFromRequest(requestInfo, out request);
- return request;
- }
-
- /// <summary>
- /// Prepares a response to inform the Client that the user has rejected the Client's authorization request.
- /// </summary>
- /// <param name="authorizationRequest">The authorization request.</param>
- /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
- /// <returns>The authorization response message to send to the Client.</returns>
- public EndUserAuthorizationFailedResponse PrepareRejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) {
- Contract.Requires<ArgumentNullException>(authorizationRequest != null);
- Contract.Ensures(Contract.Result<EndUserAuthorizationFailedResponse>() != null);
-
- if (callback == null) {
- callback = this.GetCallback(authorizationRequest);
- }
-
- var response = new EndUserAuthorizationFailedResponse(callback, authorizationRequest);
- return response;
- }
-
- /// <summary>
- /// Approves an authorization request.
- /// </summary>
- /// <param name="authorizationRequest">The authorization request to approve.</param>
- /// <param name="userName">The username of the account that approved the request (or whose data will be accessed by the client).</param>
- /// <param name="scopes">The scope of access the client should be granted. If <c>null</c>, all scopes in the original request will be granted.</param>
- /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
- /// <returns>The authorization response message to send to the Client.</returns>
- public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string userName, IEnumerable<string> scopes = null, Uri callback = null) {
- Contract.Requires<ArgumentNullException>(authorizationRequest != null);
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(userName));
- Contract.Ensures(Contract.Result<EndUserAuthorizationSuccessResponseBase>() != null);
-
- if (callback == null) {
- callback = this.GetCallback(authorizationRequest);
- }
-
- var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier);
- EndUserAuthorizationSuccessResponseBase response;
- switch (authorizationRequest.ResponseType) {
- case EndUserAuthorizationResponseType.AccessToken:
- var accessTokenResponse = new EndUserAuthorizationSuccessAccessTokenResponse(callback, authorizationRequest);
- accessTokenResponse.Lifetime = this.AuthorizationServerServices.GetAccessTokenLifetime(authorizationRequest);
- response = accessTokenResponse;
- break;
- case EndUserAuthorizationResponseType.AuthorizationCode:
- response = new EndUserAuthorizationSuccessAuthCodeResponse(callback, authorizationRequest);
- break;
- default:
- throw ErrorUtilities.ThrowInternal("Unexpected response type.");
- }
-
- response.AuthorizingUsername = userName;
-
- // Customize the approved scope if the authorization server has decided to do so.
- if (scopes != null) {
- response.Scope.ResetContents(scopes);
- }
-
- return response;
- }
-
- /// <summary>
- /// Prepares the response to an access token request.
- /// </summary>
- /// <param name="request">The request for an access token.</param>
- /// <param name="includeRefreshToken">If set to <c>true</c>, the response will include a long-lived refresh token.</param>
- /// <returns>The response message to send to the client.</returns>
- public virtual IDirectResponseProtocolMessage PrepareAccessTokenResponse(AccessTokenRequestBase request, bool includeRefreshToken = true) {
- Contract.Requires<ArgumentNullException>(request != null);
-
- var tokenRequest = (IAuthorizationCarryingRequest)request;
- var response = new AccessTokenSuccessResponse(request) {
- Lifetime = this.AuthorizationServerServices.GetAccessTokenLifetime(request),
- HasRefreshToken = includeRefreshToken,
- };
- response.Scope.ResetContents(tokenRequest.AuthorizationDescription.Scope);
- return response;
- }
-
- /// <summary>
- /// Gets the redirect URL to use for a particular authorization request.
- /// </summary>
- /// <param name="authorizationRequest">The authorization request.</param>
- /// <returns>The URL to redirect to. Never <c>null</c>.</returns>
- /// <exception cref="ProtocolException">Thrown if no callback URL could be determined.</exception>
- protected Uri GetCallback(EndUserAuthorizationRequest authorizationRequest) {
- Contract.Requires<ArgumentNullException>(authorizationRequest != null);
- Contract.Ensures(Contract.Result<Uri>() != null);
-
- var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier);
-
- // Prefer a request-specific callback to the pre-registered one (if any).
- if (authorizationRequest.Callback != null) {
- // The OAuth channel has already validated the callback parameter against
- // the authorization server's whitelist for this client.
- return authorizationRequest.Callback;
- }
-
- // Since the request didn't include a callback URL, look up the callback from
- // the client's preregistration with this authorization server.
- Uri defaultCallback = client.DefaultCallback;
- ErrorUtilities.VerifyProtocol(defaultCallback != null, OAuthStrings.NoCallback);
- return defaultCallback;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.Designer.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.Designer.cs
deleted file mode 100644
index c05a4b8..0000000
--- a/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.Designer.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-namespace DotNetOpenAuth.OAuth2 {
- partial class ClientAuthorizationView {
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.IContainer components = null;
-
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
- protected override void Dispose(bool disposing) {
- if (disposing && (components != null)) {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Component Designer generated code
-
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent() {
- this.webBrowser1 = new System.Windows.Forms.WebBrowser();
- this.SuspendLayout();
- //
- // webBrowser1
- //
- this.webBrowser1.AllowWebBrowserDrop = false;
- this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.webBrowser1.IsWebBrowserContextMenuEnabled = false;
- this.webBrowser1.Location = new System.Drawing.Point(0, 0);
- this.webBrowser1.Name = "webBrowser1";
- this.webBrowser1.Size = new System.Drawing.Size(150, 150);
- this.webBrowser1.TabIndex = 0;
- this.webBrowser1.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.WebBrowser1_Navigated);
- this.webBrowser1.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.WebBrowser1_Navigating);
- this.webBrowser1.LocationChanged += new System.EventHandler(this.WebBrowser1_LocationChanged);
- //
- // ClientAuthorizationView
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.Controls.Add(this.webBrowser1);
- this.Name = "ClientAuthorizationView";
- this.ResumeLayout(false);
-
- }
-
- #endregion
-
- private System.Windows.Forms.WebBrowser webBrowser1;
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.cs
deleted file mode 100644
index ffa217b..0000000
--- a/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.cs
+++ /dev/null
@@ -1,192 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="ClientAuthorizationView.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth2 {
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Diagnostics.Contracts;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// A WinForms control that hosts a mini-browser for hosting by native applications to
- /// allow the user to authorize the client without leaving the application.
- /// </summary>
- public partial class ClientAuthorizationView : UserControl {
- /// <summary>
- /// Initializes a new instance of the <see cref="ClientAuthorizationView"/> class.
- /// </summary>
- public ClientAuthorizationView() {
- this.InitializeComponent();
-
- this.Authorization = new AuthorizationState();
- }
-
- /// <summary>
- /// Occurs when the authorization flow has completed.
- /// </summary>
- public event EventHandler<ClientAuthorizationCompleteEventArgs> Completed;
-
- /// <summary>
- /// Gets the authorization tracking object.
- /// </summary>
- public IAuthorizationState Authorization { get; private set; }
-
- /// <summary>
- /// Gets or sets the client used to coordinate the authorization flow.
- /// </summary>
- public UserAgentClient Client { get; set; }
-
- /// <summary>
- /// Gets the set of scopes that describe the requested level of access.
- /// </summary>
- public HashSet<string> Scope {
- get { return this.Authorization.Scope; }
- }
-
- /// <summary>
- /// Gets or sets the callback URL used to indicate the flow has completed.
- /// </summary>
- public Uri Callback {
- get { return this.Authorization.Callback; }
- set { this.Authorization.Callback = value; }
- }
-
- /// <summary>
- /// Gets a value indicating whether the authorization flow has been completed.
- /// </summary>
- public bool IsCompleted {
- get { return this.Authorization == null || this.Authorization.AccessToken != null; }
- }
-
- /// <summary>
- /// Gets a value indicating whether authorization has been granted.
- /// </summary>
- /// <value>Null if <see cref="IsCompleted"/> is <c>false</c></value>
- public bool? IsGranted {
- get {
- if (this.Authorization == null) {
- return false;
- }
-
- return this.Authorization.AccessToken != null ? (bool?)true : null;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether authorization has been rejected.
- /// </summary>
- /// <value>Null if <see cref="IsCompleted"/> is <c>false</c></value>
- public bool? IsRejected {
- get {
- bool? granted = this.IsGranted;
- return granted.HasValue ? (bool?)(!granted.Value) : null;
- }
- }
-
- /// <summary>
- /// Called when the authorization flow has been completed.
- /// </summary>
- protected virtual void OnCompleted() {
- var completed = this.Completed;
- if (completed != null) {
- completed(this, new ClientAuthorizationCompleteEventArgs(this.Authorization));
- }
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Windows.Forms.UserControl.Load"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
- protected override void OnLoad(EventArgs e) {
- base.OnLoad(e);
-
- Uri authorizationUrl = this.Client.RequestUserAuthorization(this.Authorization);
- this.webBrowser1.Navigate(authorizationUrl.AbsoluteUri); // use AbsoluteUri to workaround bug in WebBrowser that calls Uri.ToString instead of Uri.AbsoluteUri leading to escaping errors.
- }
-
- /// <summary>
- /// Tests whether two URLs are equal for purposes of detecting the conclusion of authorization.
- /// </summary>
- /// <param name="location1">The first location.</param>
- /// <param name="location2">The second location.</param>
- /// <param name="components">The components to compare.</param>
- /// <returns><c>true</c> if the given components are equal.</returns>
- private static bool SignificantlyEqual(Uri location1, Uri location2, UriComponents components) {
- string value1 = location1.GetComponents(components, UriFormat.Unescaped);
- string value2 = location2.GetComponents(components, UriFormat.Unescaped);
- return string.Equals(value1, value2, StringComparison.Ordinal);
- }
-
- /// <summary>
- /// Handles the Navigating event of the webBrowser1 control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="System.Windows.Forms.WebBrowserNavigatingEventArgs"/> instance containing the event data.</param>
- private void WebBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) {
- this.ProcessLocationChanged(e.Url);
- }
-
- /// <summary>
- /// Processes changes in the URL the browser has navigated to.
- /// </summary>
- /// <param name="location">The location.</param>
- private void ProcessLocationChanged(Uri location) {
- if (SignificantlyEqual(location, this.Authorization.Callback, UriComponents.SchemeAndServer | UriComponents.Path)) {
- try {
- this.Client.ProcessUserAuthorization(location, this.Authorization);
- } catch (ProtocolException ex) {
- MessageBox.Show(ex.ToStringDescriptive());
- } finally {
- this.OnCompleted();
- }
- }
- }
-
- /// <summary>
- /// Handles the Navigated event of the webBrowser1 control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="System.Windows.Forms.WebBrowserNavigatedEventArgs"/> instance containing the event data.</param>
- private void WebBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e) {
- this.ProcessLocationChanged(e.Url);
- }
-
- /// <summary>
- /// Handles the LocationChanged event of the webBrowser1 control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
- private void WebBrowser1_LocationChanged(object sender, EventArgs e) {
- this.ProcessLocationChanged(this.webBrowser1.Url);
- }
-
- /// <summary>
- /// Describes the results of a completed authorization flow.
- /// </summary>
- public class ClientAuthorizationCompleteEventArgs : EventArgs {
- /// <summary>
- /// Initializes a new instance of the <see cref="ClientAuthorizationCompleteEventArgs"/> class.
- /// </summary>
- /// <param name="authorization">The authorization.</param>
- public ClientAuthorizationCompleteEventArgs(IAuthorizationState authorization) {
- Contract.Requires<ArgumentNullException>(authorization != null);
- this.Authorization = authorization;
- }
-
- /// <summary>
- /// Gets the authorization tracking object.
- /// </summary>
- /// <value>Null if authorization was rejected by the user.</value>
- public IAuthorizationState Authorization { get; private set; }
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.resx b/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.resx
deleted file mode 100644
index 7080a7d..0000000
--- a/src/DotNetOpenAuth.OAuth2/OAuth2/ClientAuthorizationView.resx
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
- <!--
- Microsoft ResX Schema
-
- Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
- associated with the data types.
-
- Example:
-
- ... ado.net/XML headers & schema ...
- <resheader name="resmimetype">text/microsoft-resx</resheader>
- <resheader name="version">2.0</resheader>
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
- <value>[base64 mime encoded serialized .NET Framework object]</value>
- </data>
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
- <comment>This is a comment</comment>
- </data>
-
- There are any number of "resheader" rows that contain simple
- name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
- mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
- extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
- read any of the formats listed below.
-
- mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
- : and then encoded with base64 encoding.
-
- mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
- : using a System.ComponentModel.TypeConverter
- : and then encoded with base64 encoding.
- -->
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
- <xsd:element name="root" msdata:IsDataSet="true">
- <xsd:complexType>
- <xsd:choice maxOccurs="unbounded">
- <xsd:element name="metadata">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" />
- </xsd:sequence>
- <xsd:attribute name="name" use="required" type="xsd:string" />
- <xsd:attribute name="type" type="xsd:string" />
- <xsd:attribute name="mimetype" type="xsd:string" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="assembly">
- <xsd:complexType>
- <xsd:attribute name="alias" type="xsd:string" />
- <xsd:attribute name="name" type="xsd:string" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="data">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
- <xsd:attribute ref="xml:space" />
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="resheader">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
- </xsd:sequence>
- <xsd:attribute name="name" type="xsd:string" use="required" />
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <resheader name="resmimetype">
- <value>text/microsoft-resx</value>
- </resheader>
- <resheader name="version">
- <value>2.0</value>
- </resheader>
- <resheader name="reader">
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
- <resheader name="writer">
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
- </resheader>
-</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/ClientBase.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/ClientBase.cs
deleted file mode 100644
index 51aac39..0000000
--- a/src/DotNetOpenAuth.OAuth2/OAuth2/ClientBase.cs
+++ /dev/null
@@ -1,256 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="ClientBase.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth2 {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Linq;
- using System.Net;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth2.ChannelElements;
- using DotNetOpenAuth.OAuth2.Messages;
-
- /// <summary>
- /// A base class for common OAuth Client behaviors.
- /// </summary>
- public class ClientBase {
- /// <summary>
- /// Initializes a new instance of the <see cref="ClientBase"/> class.
- /// </summary>
- /// <param name="authorizationServer">The token issuer.</param>
- /// <param name="clientIdentifier">The client identifier.</param>
- /// <param name="clientSecret">The client secret.</param>
- protected ClientBase(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, string clientSecret = null) {
- Contract.Requires<ArgumentNullException>(authorizationServer != null);
- this.AuthorizationServer = authorizationServer;
- this.Channel = new OAuth2ClientChannel();
- this.ClientIdentifier = clientIdentifier;
- this.ClientSecret = clientSecret;
- }
-
- /// <summary>
- /// Gets the token issuer.
- /// </summary>
- /// <value>The token issuer.</value>
- public AuthorizationServerDescription AuthorizationServer { get; private set; }
-
- /// <summary>
- /// Gets the OAuth channel.
- /// </summary>
- /// <value>The channel.</value>
- public Channel Channel { get; private set; }
-
- /// <summary>
- /// Gets or sets the identifier by which this client is known to the Authorization Server.
- /// </summary>
- public string ClientIdentifier { get; set; }
-
- /// <summary>
- /// Gets or sets the client secret shared with the Authorization Server.
- /// </summary>
- public string ClientSecret { get; set; }
-
- /// <summary>
- /// Adds the necessary HTTP Authorization header to an HTTP request for protected resources
- /// so that the Service Provider will allow the request through.
- /// </summary>
- /// <param name="request">The request for protected resources from the service provider.</param>
- /// <param name="accessToken">The access token previously obtained from the Authorization Server.</param>
- public static void AuthorizeRequest(HttpWebRequest request, string accessToken) {
- Contract.Requires<ArgumentNullException>(request != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(accessToken));
-
- OAuthUtilities.AuthorizeWithBearerToken(request, accessToken);
- }
-
- /// <summary>
- /// Adds the OAuth authorization token to an outgoing HTTP request, renewing a
- /// (nearly) expired access token if necessary.
- /// </summary>
- /// <param name="request">The request for protected resources from the service provider.</param>
- /// <param name="authorization">The authorization for this request previously obtained via OAuth.</param>
- public void AuthorizeRequest(HttpWebRequest request, IAuthorizationState authorization) {
- Contract.Requires<ArgumentNullException>(request != null);
- Contract.Requires<ArgumentNullException>(authorization != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(authorization.AccessToken));
- Contract.Requires<ProtocolException>(!authorization.AccessTokenExpirationUtc.HasValue || authorization.AccessTokenExpirationUtc < DateTime.UtcNow || authorization.RefreshToken != null);
-
- if (authorization.AccessTokenExpirationUtc.HasValue && authorization.AccessTokenExpirationUtc.Value < DateTime.UtcNow) {
- ErrorUtilities.VerifyProtocol(authorization.RefreshToken != null, "Access token has expired and cannot be automatically refreshed.");
- this.RefreshAuthorization(authorization);
- }
-
- AuthorizeRequest(request, authorization.AccessToken);
- }
-
- /// <summary>
- /// Refreshes a short-lived access token using a longer-lived refresh token
- /// with a new access token that has the same scope as the refresh token.
- /// The refresh token itself may also be refreshed.
- /// </summary>
- /// <param name="authorization">The authorization to update.</param>
- /// <param name="skipIfUsefulLifeExceeds">If given, the access token will <em>not</em> be refreshed if its remaining lifetime exceeds this value.</param>
- /// <returns>A value indicating whether the access token was actually renewed; <c>true</c> if it was renewed, or <c>false</c> if it still had useful life remaining.</returns>
- /// <remarks>
- /// This method may modify the value of the <see cref="IAuthorizationState.RefreshToken"/> property on
- /// the <paramref name="authorization"/> parameter if the authorization server has cycled out your refresh token.
- /// If the parameter value was updated, this method calls <see cref="IAuthorizationState.SaveChanges"/> on that instance.
- /// </remarks>
- public bool RefreshAuthorization(IAuthorizationState authorization, TimeSpan? skipIfUsefulLifeExceeds = null) {
- Contract.Requires<ArgumentNullException>(authorization != null);
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(authorization.RefreshToken));
-
- if (skipIfUsefulLifeExceeds.HasValue && authorization.AccessTokenExpirationUtc.HasValue) {
- TimeSpan usefulLifeRemaining = authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
- if (usefulLifeRemaining > skipIfUsefulLifeExceeds.Value) {
- // There is useful life remaining in the access token. Don't refresh.
- Logger.OAuth.DebugFormat("Skipping token refresh step because access token's remaining life is {0}, which exceeds {1}.", usefulLifeRemaining, skipIfUsefulLifeExceeds.Value);
- return false;
- }
- }
-
- var request = new AccessTokenRefreshRequest(this.AuthorizationServer) {
- ClientIdentifier = this.ClientIdentifier,
- ClientSecret = this.ClientSecret,
- RefreshToken = authorization.RefreshToken,
- };
-
- var response = this.Channel.Request<AccessTokenSuccessResponse>(request);
- UpdateAuthorizationWithResponse(authorization, response);
- return true;
- }
-
- /// <summary>
- /// Gets an access token that may be used for only a subset of the scope for which a given
- /// refresh token is authorized.
- /// </summary>
- /// <param name="refreshToken">The refresh token.</param>
- /// <param name="scope">The scope subset desired in the access token.</param>
- /// <returns>A description of the obtained access token, and possibly a new refresh token.</returns>
- /// <remarks>
- /// If the return value includes a new refresh token, the old refresh token should be discarded and
- /// replaced with the new one.
- /// </remarks>
- public IAuthorizationState GetScopedAccessToken(string refreshToken, HashSet<string> scope) {
- Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(refreshToken));
- Contract.Requires<ArgumentNullException>(scope != null);
- Contract.Ensures(Contract.Result<IAuthorizationState>() != null);
-
- var request = new AccessTokenRefreshRequest(this.AuthorizationServer) {
- ClientIdentifier = this.ClientIdentifier,
- ClientSecret = this.ClientSecret,
- RefreshToken = refreshToken,
- };
-
- var response = this.Channel.Request<AccessTokenSuccessResponse>(request);
- var authorization = new AuthorizationState();
- UpdateAuthorizationWithResponse(authorization, response);
-
- return authorization;
- }
-
- /// <summary>
- /// Updates the authorization state maintained by the client with the content of an outgoing response.
- /// </summary>
- /// <param name="authorizationState">The authorization state maintained by the client.</param>
- /// <param name="accessTokenSuccess">The access token containing response message.</param>
- internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, AccessTokenSuccessResponse accessTokenSuccess) {
- Contract.Requires<ArgumentNullException>(authorizationState != null);
- Contract.Requires<ArgumentNullException>(accessTokenSuccess != null);
-
- authorizationState.AccessToken = accessTokenSuccess.AccessToken;
- authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
- authorizationState.AccessTokenIssueDateUtc = DateTime.UtcNow;
-
- // The authorization server MAY choose to renew the refresh token itself.
- if (accessTokenSuccess.RefreshToken != null) {
- authorizationState.RefreshToken = accessTokenSuccess.RefreshToken;
- }
-
- // An included scope parameter in the response only describes the access token's scope.
- // Don't update the whole authorization state object with that scope because that represents
- // the refresh token's original scope.
- if ((authorizationState.Scope == null || authorizationState.Scope.Count == 0) && accessTokenSuccess.Scope != null) {
- authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
- }
-
- authorizationState.SaveChanges();
- }
-
- /// <summary>
- /// Updates the authorization state maintained by the client with the content of an outgoing response.
- /// </summary>
- /// <param name="authorizationState">The authorization state maintained by the client.</param>
- /// <param name="accessTokenSuccess">The access token containing response message.</param>
- internal static void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, EndUserAuthorizationSuccessAccessTokenResponse accessTokenSuccess) {
- Contract.Requires<ArgumentNullException>(authorizationState != null);
- Contract.Requires<ArgumentNullException>(accessTokenSuccess != null);
-
- authorizationState.AccessToken = accessTokenSuccess.AccessToken;
- authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime;
- authorizationState.AccessTokenIssueDateUtc = DateTime.UtcNow;
- if (accessTokenSuccess.Scope != null && accessTokenSuccess.Scope != authorizationState.Scope) {
- if (authorizationState.Scope != null) {
- Logger.OAuth.InfoFormat(
- "Requested scope of \"{0}\" changed to \"{1}\" by authorization server.",
- authorizationState.Scope,
- accessTokenSuccess.Scope);
- }
-
- authorizationState.Scope.ResetContents(accessTokenSuccess.Scope);
- }
-
- authorizationState.SaveChanges();
- }
-
- /// <summary>
- /// Updates authorization state with a success response from the Authorization Server.
- /// </summary>
- /// <param name="authorizationState">The authorization state to update.</param>
- /// <param name="authorizationSuccess">The authorization success message obtained from the authorization server.</param>
- internal void UpdateAuthorizationWithResponse(IAuthorizationState authorizationState, EndUserAuthorizationSuccessAuthCodeResponse authorizationSuccess) {
- Contract.Requires<ArgumentNullException>(authorizationState != null);
- Contract.Requires<ArgumentNullException>(authorizationSuccess != null);
-
- var accessTokenRequest = new AccessTokenAuthorizationCodeRequest(this.AuthorizationServer) {
- ClientIdentifier = this.ClientIdentifier,
- ClientSecret = this.ClientSecret,
- Callback = authorizationState.Callback,
- AuthorizationCode = authorizationSuccess.AuthorizationCode,
- };
- IProtocolMessage accessTokenResponse = this.Channel.Request(accessTokenRequest);
- var accessTokenSuccess = accessTokenResponse as AccessTokenSuccessResponse;
- var failedAccessTokenResponse = accessTokenResponse as AccessTokenFailedResponse;
- if (accessTokenSuccess != null) {
- UpdateAuthorizationWithResponse(authorizationState, accessTokenSuccess);
- } else {
- authorizationState.Delete();
- string error = failedAccessTokenResponse != null ? failedAccessTokenResponse.Error : "(unknown)";
- ErrorUtilities.ThrowProtocol(OAuthStrings.CannotObtainAccessTokenWithReason, error);
- }
- }
-
- /// <summary>
- /// Calculates the fraction of life remaining in an access token.
- /// </summary>
- /// <param name="authorization">The authorization to measure.</param>
- /// <returns>A fractional number no greater than 1. Could be negative if the access token has already expired.</returns>
- private static double ProportionalLifeRemaining(IAuthorizationState authorization) {
- Contract.Requires<ArgumentNullException>(authorization != null);
- Contract.Requires<ArgumentException>(authorization.AccessTokenIssueDateUtc.HasValue);
- Contract.Requires<ArgumentException>(authorization.AccessTokenExpirationUtc.HasValue);
-
- // Calculate what % of the total life this access token has left.
- TimeSpan totalLifetime = authorization.AccessTokenExpirationUtc.Value - authorization.AccessTokenIssueDateUtc.Value;
- TimeSpan elapsedLifetime = DateTime.UtcNow - authorization.AccessTokenIssueDateUtc.Value;
- double proportionLifetimeRemaining = 1 - (elapsedLifetime.TotalSeconds / totalLifetime.TotalSeconds);
- return proportionLifetimeRemaining;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/ResourceServer.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/ResourceServer.cs
deleted file mode 100644
index a5baef0..0000000
--- a/src/DotNetOpenAuth.OAuth2/OAuth2/ResourceServer.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="ResourceServer.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth2 {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Net;
- using System.Security.Principal;
- using System.ServiceModel.Channels;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Web;
- using ChannelElements;
- using Messages;
- using Messaging;
-
- /// <summary>
- /// Provides services for validating OAuth access tokens.
- /// </summary>
- public class ResourceServer {
- /// <summary>
- /// Initializes a new instance of the <see cref="ResourceServer"/> class.
- /// </summary>
- /// <param name="accessTokenAnalyzer">The access token analyzer.</param>
- public ResourceServer(IAccessTokenAnalyzer accessTokenAnalyzer) {
- Contract.Requires<ArgumentNullException>(accessTokenAnalyzer != null);
-
- this.AccessTokenAnalyzer = accessTokenAnalyzer;
- this.Channel = new OAuth2ResourceServerChannel();
- }
-
- /// <summary>
- /// Gets the access token analyzer.
- /// </summary>
- /// <value>The access token analyzer.</value>
- public IAccessTokenAnalyzer AccessTokenAnalyzer { get; private set; }
-
- /// <summary>
- /// Gets the channel.
- /// </summary>
- /// <value>The channel.</value>
- internal OAuth2ResourceServerChannel Channel { get; private set; }
-
- /// <summary>
- /// Discovers what access the client should have considering the access token in the current request.
- /// </summary>
- /// <param name="userName">The name on the account the client has access to.</param>
- /// <param name="scope">The set of operations the client is authorized for.</param>
- /// <returns>An error to return to the client if access is not authorized; <c>null</c> if access is granted.</returns>
- [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#", Justification = "Try pattern")]
- [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")]
- public OutgoingWebResponse VerifyAccess(out string userName, out HashSet<string> scope) {
- return this.VerifyAccess(this.Channel.GetRequestFromContext(), out userName, out scope);
- }
-
- /// <summary>
- /// Discovers what access the client should have considering the access token in the current request.
- /// </summary>
- /// <param name="httpRequestInfo">The HTTP request info.</param>
- /// <param name="userName">The name on the account the client has access to.</param>
- /// <param name="scope">The set of operations the client is authorized for.</param>
- /// <returns>
- /// An error to return to the client if access is not authorized; <c>null</c> if access is granted.
- /// </returns>
- [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")]
- [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "Try pattern")]
- public virtual OutgoingWebResponse VerifyAccess(HttpRequestInfo httpRequestInfo, out string userName, out HashSet<string> scope) {
- Contract.Requires<ArgumentNullException>(httpRequestInfo != null);
-
- AccessProtectedResourceRequest request = null;
- try {
- if (this.Channel.TryReadFromRequest<AccessProtectedResourceRequest>(httpRequestInfo, out request)) {
- if (this.AccessTokenAnalyzer.TryValidateAccessToken(request, request.AccessToken, out userName, out scope)) {
- // No errors to return.
- return null;
- }
-
- throw ErrorUtilities.ThrowProtocol("Bad access token");
- } else {
- var response = new UnauthorizedResponse(new ProtocolException("Missing access token"));
-
- userName = null;
- scope = null;
- return this.Channel.PrepareResponse(response);
- }
- } catch (ProtocolException ex) {
- var response = request != null ? new UnauthorizedResponse(request, ex) : new UnauthorizedResponse(ex);
-
- userName = null;
- scope = null;
- return this.Channel.PrepareResponse(response);
- }
- }
-
- /// <summary>
- /// Discovers what access the client should have considering the access token in the current request.
- /// </summary>
- /// <param name="httpRequestInfo">The HTTP request info.</param>
- /// <param name="principal">The principal that contains the user and roles that the access token is authorized for.</param>
- /// <returns>
- /// An error to return to the client if access is not authorized; <c>null</c> if access is granted.
- /// </returns>
- [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")]
- public virtual OutgoingWebResponse VerifyAccess(HttpRequestInfo httpRequestInfo, out IPrincipal principal) {
- string username;
- HashSet<string> scope;
- var result = this.VerifyAccess(httpRequestInfo, out username, out scope);
- principal = result == null ? new OAuth.ChannelElements.OAuthPrincipal(username, scope != null ? scope.ToArray() : new string[0]) : null;
- return result;
- }
-
- /// <summary>
- /// Discovers what access the client should have considering the access token in the current request.
- /// </summary>
- /// <param name="request">HTTP details from an incoming WCF message.</param>
- /// <param name="requestUri">The URI of the WCF service endpoint.</param>
- /// <param name="principal">The principal that contains the user and roles that the access token is authorized for.</param>
- /// <returns>
- /// An error to return to the client if access is not authorized; <c>null</c> if access is granted.
- /// </returns>
- [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Try pattern")]
- [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "Try pattern")]
- public virtual OutgoingWebResponse VerifyAccess(HttpRequestMessageProperty request, Uri requestUri, out IPrincipal principal) {
- Contract.Requires<ArgumentNullException>(request != null);
- Contract.Requires<ArgumentNullException>(requestUri != null);
-
- return this.VerifyAccess(new HttpRequestInfo(request, requestUri), out principal);
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/UserAgentClient.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/UserAgentClient.cs
deleted file mode 100644
index e23eca4..0000000
--- a/src/DotNetOpenAuth.OAuth2/OAuth2/UserAgentClient.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="UserAgentClient.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth2 {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth2.Messages;
-
- /// <summary>
- /// The OAuth client for the user-agent flow, providing services for installed apps
- /// and in-browser Javascript widgets.
- /// </summary>
- public class UserAgentClient : ClientBase {
- /// <summary>
- /// Initializes a new instance of the <see cref="UserAgentClient"/> class.
- /// </summary>
- /// <param name="authorizationServer">The token issuer.</param>
- /// <param name="clientIdentifier">The client identifier.</param>
- /// <param name="clientSecret">The client secret.</param>
- public UserAgentClient(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, string clientSecret = null)
- : base(authorizationServer, clientIdentifier, clientSecret) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="UserAgentClient"/> class.
- /// </summary>
- /// <param name="authorizationEndpoint">The authorization endpoint.</param>
- /// <param name="tokenEndpoint">The token endpoint.</param>
- /// <param name="clientIdentifier">The client identifier.</param>
- /// <param name="clientSecret">The client secret.</param>
- public UserAgentClient(Uri authorizationEndpoint, Uri tokenEndpoint, string clientIdentifier = null, string clientSecret = null)
- : this(new AuthorizationServerDescription { AuthorizationEndpoint = authorizationEndpoint, TokenEndpoint = tokenEndpoint }, clientIdentifier, clientSecret) {
- Contract.Requires<ArgumentNullException>(authorizationEndpoint != null);
- Contract.Requires<ArgumentNullException>(tokenEndpoint != null);
- }
-
- /// <summary>
- /// Generates a URL that the user's browser can be directed to in order to authorize
- /// this client to access protected data at some resource server.
- /// </summary>
- /// <param name="scope">The scope of authorized access requested.</param>
- /// <param name="state">The client state that should be returned with the authorization response.</param>
- /// <param name="returnTo">The URL that the authorization response should be sent to via a user-agent redirect.</param>
- /// <returns>
- /// A fully-qualified URL suitable to initiate the authorization flow.
- /// </returns>
- public Uri RequestUserAuthorization(IEnumerable<string> scope = null, string state = null, Uri returnTo = null) {
- var authorization = new AuthorizationState(scope) {
- Callback = returnTo,
- };
-
- return this.RequestUserAuthorization(authorization);
- }
-
- /// <summary>
- /// Generates a URL that the user's browser can be directed to in order to authorize
- /// this client to access protected data at some resource server.
- /// </summary>
- /// <param name="authorization">The authorization state that is tracking this particular request. Optional.</param>
- /// <param name="state">The client state that should be returned with the authorization response.</param>
- /// <returns>
- /// A fully-qualified URL suitable to initiate the authorization flow.
- /// </returns>
- public Uri RequestUserAuthorization(IAuthorizationState authorization, string state = null) {
- Contract.Requires<ArgumentNullException>(authorization != null);
- Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier));
-
- if (authorization.Callback == null) {
- authorization.Callback = new Uri("http://localhost/");
- }
-
- var request = new EndUserAuthorizationRequest(this.AuthorizationServer) {
- ClientIdentifier = this.ClientIdentifier,
- Callback = authorization.Callback,
- ClientState = state,
- };
- request.Scope.ResetContents(authorization.Scope);
-
- return this.Channel.PrepareResponse(request).GetDirectUriRequest(this.Channel);
- }
-
- /// <summary>
- /// Scans the incoming request for an authorization response message.
- /// </summary>
- /// <param name="actualRedirectUrl">The actual URL of the incoming HTTP request.</param>
- /// <param name="authorizationState">The authorization.</param>
- /// <returns>The granted authorization, or <c>null</c> if the incoming HTTP request did not contain an authorization server response or authorization was rejected.</returns>
- public IAuthorizationState ProcessUserAuthorization(Uri actualRedirectUrl, IAuthorizationState authorizationState = null) {
- Contract.Requires<ArgumentNullException>(actualRedirectUrl != null);
-
- if (authorizationState == null) {
- authorizationState = new AuthorizationState();
- }
-
- var carrier = new HttpRequestInfo("GET", actualRedirectUrl, actualRedirectUrl.PathAndQuery, new System.Net.WebHeaderCollection(), null);
- IDirectedProtocolMessage response = this.Channel.ReadFromRequest(carrier);
- if (response == null) {
- return null;
- }
-
- EndUserAuthorizationSuccessAccessTokenResponse accessTokenSuccess;
- EndUserAuthorizationSuccessAuthCodeResponse authCodeSuccess;
- EndUserAuthorizationFailedResponse failure;
- if ((accessTokenSuccess = response as EndUserAuthorizationSuccessAccessTokenResponse) != null) {
- UpdateAuthorizationWithResponse(authorizationState, accessTokenSuccess);
- } else if ((authCodeSuccess = response as EndUserAuthorizationSuccessAuthCodeResponse) != null) {
- this.UpdateAuthorizationWithResponse(authorizationState, authCodeSuccess);
- } else if ((failure = response as EndUserAuthorizationFailedResponse) != null) {
- authorizationState.Delete();
- return null;
- }
-
- return authorizationState;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/WebServerClient.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/WebServerClient.cs
deleted file mode 100644
index a6fae13..0000000
--- a/src/DotNetOpenAuth.OAuth2/OAuth2/WebServerClient.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="WebServerClient.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth2 {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Net;
- using System.Text;
- using System.Web;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth2.Messages;
-
- /// <summary>
- /// An OAuth 2.0 consumer designed for web applications.
- /// </summary>
- public class WebServerClient : ClientBase {
- /// <summary>
- /// Initializes a new instance of the <see cref="WebServerClient"/> class.
- /// </summary>
- /// <param name="authorizationServer">The authorization server.</param>
- /// <param name="clientIdentifier">The client identifier.</param>
- /// <param name="clientSecret">The client secret.</param>
- public WebServerClient(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, string clientSecret = null)
- : base(authorizationServer, clientIdentifier, clientSecret) {
- }
-
- /// <summary>
- /// Gets or sets an optional component that gives you greater control to record and influence the authorization process.
- /// </summary>
- /// <value>The authorization tracker.</value>
- public IClientAuthorizationTracker AuthorizationTracker { get; set; }
-
- /// <summary>
- /// Prepares a request for user authorization from an authorization server.
- /// </summary>
- /// <param name="scope">The scope of authorized access requested.</param>
- /// <param name="state">The state of the client that should be sent back with the authorization response.</param>
- /// <param name="returnTo">The URL the authorization server should redirect the browser (typically on this site) to when the authorization is completed. If null, the current request's URL will be used.</param>
- public void RequestUserAuthorization(IEnumerable<string> scope = null, string state = null, Uri returnTo = null) {
- var authorizationState = new AuthorizationState(scope) {
- Callback = returnTo,
- };
- this.PrepareRequestUserAuthorization(authorizationState, state).Respond();
- }
-
- /// <summary>
- /// Prepares a request for user authorization from an authorization server.
- /// </summary>
- /// <param name="scopes">The scope of authorized access requested.</param>
- /// <param name="state">The state of the client that should be sent back with the authorization response.</param>
- /// <returns>The authorization request.</returns>
- public OutgoingWebResponse PrepareRequestUserAuthorization(IEnumerable<string> scopes = null, string state = null) {
- var authorizationState = new AuthorizationState(scopes);
- return this.PrepareRequestUserAuthorization(authorizationState, state);
- }
-
- /// <summary>
- /// Prepares a request for user authorization from an authorization server.
- /// </summary>
- /// <param name="authorization">The authorization state to associate with this particular request.</param>
- /// <param name="state">The state of the client that should be sent back with the authorization response.</param>
- /// <returns>The authorization request.</returns>
- public OutgoingWebResponse PrepareRequestUserAuthorization(IAuthorizationState authorization, string state = null) {
- Contract.Requires<ArgumentNullException>(authorization != null);
- Contract.Requires<InvalidOperationException>(authorization.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
- Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier));
- Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);
-
- if (authorization.Callback == null) {
- authorization.Callback = this.Channel.GetRequestFromContext().UrlBeforeRewriting
- .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationSuccessResponseBase), Protocol.Default.Version))
- .StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(typeof(EndUserAuthorizationFailedResponse), Protocol.Default.Version));
- authorization.SaveChanges();
- }
-
- var request = new EndUserAuthorizationRequest(this.AuthorizationServer) {
- ClientIdentifier = this.ClientIdentifier,
- Callback = authorization.Callback,
- ClientState = state,
- };
- request.Scope.ResetContents(authorization.Scope);
-
- return this.Channel.PrepareResponse(request);
- }
-
- /// <summary>
- /// Processes the authorization response from an authorization server, if available.
- /// </summary>
- /// <param name="request">The incoming HTTP request that may carry an authorization response.</param>
- /// <returns>The authorization state that contains the details of the authorization.</returns>
- public IAuthorizationState ProcessUserAuthorization(HttpRequestInfo request = null) {
- Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier));
- Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientSecret));
-
- if (request == null) {
- request = this.Channel.GetRequestFromContext();
- }
-
- IMessageWithClientState response;
- if (this.Channel.TryReadFromRequest<IMessageWithClientState>(request, out response)) {
- Uri callback = MessagingUtilities.StripMessagePartsFromQueryString(request.UrlBeforeRewriting, this.Channel.MessageDescriptions.Get(response));
- IAuthorizationState authorizationState;
- if (this.AuthorizationTracker != null) {
- authorizationState = this.AuthorizationTracker.GetAuthorizationState(callback, response.ClientState);
- ErrorUtilities.VerifyProtocol(authorizationState != null, "Unexpected OAuth authorization response received with callback and client state that does not match an expected value.");
- } else {
- authorizationState = new AuthorizationState { Callback = callback };
- }
- var success = response as EndUserAuthorizationSuccessAuthCodeResponse;
- var failure = response as EndUserAuthorizationFailedResponse;
- ErrorUtilities.VerifyProtocol(success != null || failure != null, MessagingStrings.UnexpectedMessageReceivedOfMany);
- if (success != null) {
- this.UpdateAuthorizationWithResponse(authorizationState, success);
- } else { // failure
- Logger.OAuth.Info("User refused to grant the requested authorization at the Authorization Server.");
- authorizationState.Delete();
- }
-
- return authorizationState;
- }
-
- return null;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth2/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.OAuth2/Properties/AssemblyInfo.cs
index ad8decc..67eed6d 100644
--- a/src/DotNetOpenAuth.OAuth2/Properties/AssemblyInfo.cs
+++ b/src/DotNetOpenAuth.OAuth2/Properties/AssemblyInfo.cs
@@ -47,6 +47,12 @@ using System.Web.UI;
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("DotNetOpenAuth.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")]
+[assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth2.AuthorizationServer, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")]
+[assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth2.ResourceServer, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")]
+[assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth2.Client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")]
#else
[assembly: InternalsVisibleTo("DotNetOpenAuth.Test")]
+[assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth2.AuthorizationServer")]
+[assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth2.ResourceServer")]
+[assembly: InternalsVisibleTo("DotNetOpenAuth.OAuth2.Client")]
#endif