diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2011-08-01 06:45:34 -0600 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2011-08-01 06:45:34 -0600 |
commit | ee09a67e9f3923b01f86a90a31f91c138d0464a6 (patch) | |
tree | 813b5e1cc9fb522912f98043f500aade712086e6 /src/DotNetOpenAuth.OAuth2/OAuth2 | |
parent | abc4fe5b0db2efd8a3e114c16389572d57ffee6b (diff) | |
download | DotNetOpenAuth-ee09a67e9f3923b01f86a90a31f91c138d0464a6.zip DotNetOpenAuth-ee09a67e9f3923b01f86a90a31f91c138d0464a6.tar.gz DotNetOpenAuth-ee09a67e9f3923b01f86a90a31f91c138d0464a6.tar.bz2 |
Broke out OAuth 2 into 4 separate assemblies.
Diffstat (limited to 'src/DotNetOpenAuth.OAuth2/OAuth2')
8 files changed, 0 insertions, 1271 deletions
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; - } - } -} |