summaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
Diffstat (limited to 'samples')
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj6
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/Facebook/FacebookClient.cs29
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/Facebook/FacebookGraph.cs54
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/InMemoryClientTokenManager.cs53
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/TokenManager.cs18
-rw-r--r--samples/OAuthConsumer/Default.aspx1
-rw-r--r--samples/OAuthConsumer/Facebook.aspx16
-rw-r--r--samples/OAuthConsumer/Facebook.aspx.cs32
-rw-r--r--samples/OAuthConsumer/Facebook.aspx.designer.cs33
-rw-r--r--samples/OAuthConsumer/OAuthConsumer.csproj19
-rw-r--r--samples/OAuthConsumer/SampleWcf.aspx2
-rw-r--r--samples/OAuthConsumer/SampleWcf.aspx.cs8
-rw-r--r--samples/OAuthConsumer/SampleWcf2.aspx23
-rw-r--r--samples/OAuthConsumer/SampleWcf2.aspx.cs112
-rw-r--r--samples/OAuthConsumer/SampleWcf2.aspx.designer.cs96
-rw-r--r--samples/OAuthConsumer/Web.config8
-rw-r--r--samples/OAuthConsumerWpf/Authorize2.xaml11
-rw-r--r--samples/OAuthConsumerWpf/Authorize2.xaml.cs56
-rw-r--r--samples/OAuthConsumerWpf/MainWindow.xaml322
-rw-r--r--samples/OAuthConsumerWpf/MainWindow.xaml.cs43
-rw-r--r--samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj11
-rw-r--r--samples/OAuthServiceProvider/Code/Global.cs10
-rw-r--r--samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs60
-rw-r--r--samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs58
-rw-r--r--samples/OAuthServiceProvider/Members/Authorize.aspx2
-rw-r--r--samples/OAuthServiceProvider/Members/Authorize2.aspx53
-rw-r--r--samples/OAuthServiceProvider/Members/Authorize2.aspx.cs53
-rw-r--r--samples/OAuthServiceProvider/Members/Authorize2.aspx.designer.cs123
-rw-r--r--samples/OAuthServiceProvider/OAuth.ashx2
-rw-r--r--samples/OAuthServiceProvider/OAuth2.ashx1
-rw-r--r--samples/OAuthServiceProvider/OAuth2.ashx.cs53
-rw-r--r--samples/OAuthServiceProvider/OAuthServiceProvider.csproj13
-rw-r--r--samples/OAuthServiceProvider/Web.config5
33 files changed, 1230 insertions, 156 deletions
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj b/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
index 6739bf9..7e1a0dd 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
+++ b/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
@@ -72,6 +72,8 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
+ <Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -86,11 +88,15 @@
<Compile Include="CustomExtensions\Acme.cs" />
<Compile Include="CustomExtensions\AcmeRequest.cs" />
<Compile Include="CustomExtensions\AcmeResponse.cs" />
+ <Compile Include="Facebook\FacebookClient.cs" />
+ <Compile Include="Facebook\FacebookGraph.cs" />
<Compile Include="GoogleConsumer.cs" />
+ <Compile Include="InMemoryClientTokenManager.cs" />
<Compile Include="InMemoryTokenManager.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="TokenManager.cs" />
<Compile Include="TwitterConsumer.cs" />
<Compile Include="Util.cs" />
<Compile Include="YubikeyRelyingParty.cs" />
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/Facebook/FacebookClient.cs b/samples/DotNetOpenAuth.ApplicationBlock/Facebook/FacebookClient.cs
new file mode 100644
index 0000000..2f3840e
--- /dev/null
+++ b/samples/DotNetOpenAuth.ApplicationBlock/Facebook/FacebookClient.cs
@@ -0,0 +1,29 @@
+//-----------------------------------------------------------------------
+// <copyright file="FacebookClient.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.ApplicationBlock {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuthWrap;
+
+ public class FacebookClient : WebServerClient {
+ private static readonly AuthorizationServerDescription FacebookDescription = new AuthorizationServerDescription {
+ TokenEndpoint = new Uri("https://graph.facebook.com/oauth/access_token"),
+ AuthorizationEndpoint = new Uri("https://graph.facebook.com/oauth/authorize"),
+ };
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FacebookClient"/> class.
+ /// </summary>
+ public FacebookClient() : base(FacebookDescription) {
+ this.TokenManager = new TokenManager();
+ }
+ }
+}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/Facebook/FacebookGraph.cs b/samples/DotNetOpenAuth.ApplicationBlock/Facebook/FacebookGraph.cs
new file mode 100644
index 0000000..0e878c1
--- /dev/null
+++ b/samples/DotNetOpenAuth.ApplicationBlock/Facebook/FacebookGraph.cs
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------
+// <copyright file="FacebookGraph.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.ApplicationBlock.Facebook {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Runtime.Serialization;
+ using System.Runtime.Serialization.Json;
+ using System.Text;
+
+ [DataContract]
+ public class FacebookGraph {
+ private static DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(FacebookGraph));
+
+ [DataMember(Name = "id")]
+ public int Id { get; set; }
+
+ [DataMember(Name = "name")]
+ public string Name { get; set; }
+
+ [DataMember(Name = "first_name")]
+ public string FirstName { get; set; }
+
+ [DataMember(Name = "last_name")]
+ public string LastName { get; set; }
+
+ [DataMember(Name = "link")]
+ public Uri Link { get; set; }
+
+ [DataMember(Name = "birthday")]
+ public string Birthday { get; set; }
+
+ public static FacebookGraph Deserialize(string json) {
+ if (String.IsNullOrEmpty(json)) {
+ throw new ArgumentNullException("json");
+ }
+
+ return Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(json)));
+ }
+
+ public static FacebookGraph Deserialize(Stream jsonStream) {
+ if (jsonStream == null) {
+ throw new ArgumentNullException("jsonStream");
+ }
+
+ return (FacebookGraph)jsonSerializer.ReadObject(jsonStream);
+ }
+ }
+}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/InMemoryClientTokenManager.cs b/samples/DotNetOpenAuth.ApplicationBlock/InMemoryClientTokenManager.cs
new file mode 100644
index 0000000..4c86df7
--- /dev/null
+++ b/samples/DotNetOpenAuth.ApplicationBlock/InMemoryClientTokenManager.cs
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryClientTokenManager.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.ApplicationBlock {
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.Text;
+ using System.Threading;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuthWrap;
+
+#if SAMPLESONLY
+ internal class InMemoryClientTokenManager : IClientTokenManager {
+ private readonly Dictionary<int, IAuthorizationState> savedStates = new Dictionary<int, IAuthorizationState>();
+ private int stateCounter;
+
+ #region Implementation of IClientTokenManager
+
+ /// <summary>
+ /// Gets the state of the authorization for a given callback URL and client state.
+ /// </summary>
+ /// <param name="callbackUrl">The callback URL.</param>
+ /// <param name="clientState">State of the client stored at the beginning of an authorization request.</param>
+ /// <returns>The authorization state; may be <c>null</c> if no authorization state matches.</returns>
+ public IAuthorizationState GetAuthorizationState(Uri callbackUrl, string clientState) {
+ IAuthorizationState state;
+ if (this.savedStates.TryGetValue(int.Parse(clientState), out state)) {
+ if (state.Callback != callbackUrl) {
+ throw new DotNetOpenAuth.Messaging.ProtocolException("Client state and callback URL do not match.");
+ }
+ }
+
+ return state;
+ }
+
+ #endregion
+
+ internal IAuthorizationState NewAuthorization(string scope, out string clientState) {
+ int counter = Interlocked.Increment(ref this.stateCounter);
+ clientState = counter.ToString(CultureInfo.InvariantCulture);
+ return this.savedStates[counter] = new AuthorizationState {
+ Scope = scope,
+ };
+ }
+ }
+#endif
+}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/TokenManager.cs b/samples/DotNetOpenAuth.ApplicationBlock/TokenManager.cs
new file mode 100644
index 0000000..22099a3
--- /dev/null
+++ b/samples/DotNetOpenAuth.ApplicationBlock/TokenManager.cs
@@ -0,0 +1,18 @@
+//-----------------------------------------------------------------------
+// <copyright file="TokenManager.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.ApplicationBlock {
+ using System;
+ using DotNetOpenAuth.OAuthWrap;
+
+ public class TokenManager : IClientTokenManager {
+ public IAuthorizationState GetAuthorizationState(Uri callbackUrl, string clientState) {
+ return new AuthorizationState {
+ Callback = callbackUrl,
+ };
+ }
+ }
+}
diff --git a/samples/OAuthConsumer/Default.aspx b/samples/OAuthConsumer/Default.aspx
index c952877..f3bceb6 100644
--- a/samples/OAuthConsumer/Default.aspx
+++ b/samples/OAuthConsumer/Default.aspx
@@ -9,6 +9,7 @@
<li><a href="GoogleAddressBook.aspx">Download your Gmail address book</a></li>
<li><a href="Twitter.aspx">Get your Twitter updates</a></li>
<li><a href="SignInWithTwitter.aspx">Sign In With Twitter</a></li>
+ <li><a href="Facebook.aspx">Sign in with Facebook</a></li>
<li><a href="SampleWcf.aspx">Interop with Service Provider sample using WCF w/ OAuth</a></li>
</ul>
</asp:Content>
diff --git a/samples/OAuthConsumer/Facebook.aspx b/samples/OAuthConsumer/Facebook.aspx
new file mode 100644
index 0000000..44fc46e
--- /dev/null
+++ b/samples/OAuthConsumer/Facebook.aspx
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OAuthConsumer.Facebook" Codebehind="Facebook.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ Welcome,
+ <asp:Label Text="[name]" ID="nameLabel" runat="server" />
+ </div>
+ </form>
+</body>
+</html>
diff --git a/samples/OAuthConsumer/Facebook.aspx.cs b/samples/OAuthConsumer/Facebook.aspx.cs
new file mode 100644
index 0000000..5935859
--- /dev/null
+++ b/samples/OAuthConsumer/Facebook.aspx.cs
@@ -0,0 +1,32 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Configuration;
+ using System.Net;
+ using System.Web;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.ApplicationBlock.Facebook;
+ using DotNetOpenAuth.OAuthWrap;
+
+ public partial class Facebook : System.Web.UI.Page {
+ private static readonly FacebookClient client = new FacebookClient {
+ ClientIdentifier = ConfigurationManager.AppSettings["facebookAppID"],
+ ClientSecret = ConfigurationManager.AppSettings["facebookAppSecret"],
+ };
+
+ protected void Page_Load(object sender, EventArgs e) {
+ IAuthorizationState authorization = client.ProcessUserAuthorization();
+ if (authorization == null) {
+ // Kick off authorization request
+ client.Channel.Send(client.PrepareRequestUserAuthorization());
+ } else {
+ var request = WebRequest.Create("https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
+ using (var response = request.GetResponse()) {
+ using (var responseStream = response.GetResponseStream()) {
+ var graph = FacebookGraph.Deserialize(responseStream);
+ this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OAuthConsumer/Facebook.aspx.designer.cs b/samples/OAuthConsumer/Facebook.aspx.designer.cs
new file mode 100644
index 0000000..a3f8195
--- /dev/null
+++ b/samples/OAuthConsumer/Facebook.aspx.designer.cs
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class Facebook {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// nameLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label nameLabel;
+ }
+}
diff --git a/samples/OAuthConsumer/OAuthConsumer.csproj b/samples/OAuthConsumer/OAuthConsumer.csproj
index 8092ba2..4f01f97 100644
--- a/samples/OAuthConsumer/OAuthConsumer.csproj
+++ b/samples/OAuthConsumer/OAuthConsumer.csproj
@@ -57,6 +57,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="Default.aspx" />
+ <Content Include="Facebook.aspx" />
<Content Include="favicon.ico" />
<Content Include="Global.asax" />
<Content Include="GoogleAddressBook.aspx" />
@@ -69,6 +70,7 @@
<Generator>WCF Proxy Generator</Generator>
<LastGenOutput>Reference.cs</LastGenOutput>
</None>
+ <Content Include="SampleWcf2.aspx" />
<Content Include="SignInWithTwitter.aspx" />
<Content Include="TracePage.aspx" />
<Content Include="Twitter.aspx" />
@@ -81,9 +83,19 @@
</None>
</ItemGroup>
<ItemGroup>
+ <Compile Include="..\DotNetOpenAuth.ApplicationBlock\InMemoryClientTokenManager.cs">
+ <Link>Code\InMemoryClientTokenManager.cs</Link>
+ </Compile>
<Compile Include="..\DotNetOpenAuth.ApplicationBlock\InMemoryTokenManager.cs">
<Link>Code\InMemoryTokenManager.cs</Link>
</Compile>
+ <Compile Include="Facebook.aspx.cs">
+ <DependentUpon>Facebook.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Facebook.aspx.designer.cs">
+ <DependentUpon>Facebook.aspx</DependentUpon>
+ </Compile>
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
@@ -97,6 +109,13 @@
<Compile Include="SampleWcf.aspx.designer.cs">
<DependentUpon>SampleWcf.aspx</DependentUpon>
</Compile>
+ <Compile Include="SampleWcf2.aspx.cs">
+ <DependentUpon>SampleWcf2.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="SampleWcf2.aspx.designer.cs">
+ <DependentUpon>SampleWcf2.aspx</DependentUpon>
+ </Compile>
<Compile Include="Service References\SampleServiceProvider\Reference.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
diff --git a/samples/OAuthConsumer/SampleWcf.aspx b/samples/OAuthConsumer/SampleWcf.aspx
index fb318ce..fcec089 100644
--- a/samples/OAuthConsumer/SampleWcf.aspx
+++ b/samples/OAuthConsumer/SampleWcf.aspx
@@ -1,4 +1,4 @@
-<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthConsumer.SampleWcf" Codebehind="SampleWcf.aspx.cs" %>
+<%@ Page Title="OAuth 1.0a consumer" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthConsumer.SampleWcf" Codebehind="SampleWcf.aspx.cs" %>
<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
<fieldset title="Authorization">
diff --git a/samples/OAuthConsumer/SampleWcf.aspx.cs b/samples/OAuthConsumer/SampleWcf.aspx.cs
index 489e294..74c6e6a 100644
--- a/samples/OAuthConsumer/SampleWcf.aspx.cs
+++ b/samples/OAuthConsumer/SampleWcf.aspx.cs
@@ -39,10 +39,10 @@
string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>()
where item.Selected
select item.Value).ToArray();
- string scope = string.Join("|", scopes);
+ string scope = string.Join(" ", scopes);
var requestParams = new Dictionary<string, string> {
- { "scope", scope },
- };
+ { "scope", scope },
+ };
var response = consumer.PrepareRequestUserAuthorization(callback.Uri, requestParams, null);
consumer.Channel.Send(response);
}
@@ -83,7 +83,7 @@
WebConsumer consumer = this.CreateConsumer();
WebRequest httpRequest = consumer.PrepareAuthorizedRequest(serviceEndpoint, accessToken);
- HttpRequestMessageProperty httpDetails = new HttpRequestMessageProperty();
+ var httpDetails = new HttpRequestMessageProperty();
httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization];
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) {
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpDetails;
diff --git a/samples/OAuthConsumer/SampleWcf2.aspx b/samples/OAuthConsumer/SampleWcf2.aspx
new file mode 100644
index 0000000..797a2fc
--- /dev/null
+++ b/samples/OAuthConsumer/SampleWcf2.aspx
@@ -0,0 +1,23 @@
+<%@ Page Title="OAuth 2.0 client (web server flow)" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthConsumer.SampleWcf2" Codebehind="SampleWcf2.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <fieldset title="Authorization">
+ <asp:CheckBoxList runat="server" ID="scopeList">
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetName">GetName</asp:ListItem>
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetAge">GetAge</asp:ListItem>
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetFavoriteSites">GetFavoriteSites</asp:ListItem>
+ </asp:CheckBoxList>
+ <asp:Button ID="getAuthorizationButton" runat="server" Text="Get Authorization" OnClick="getAuthorizationButton_Click" />
+ <asp:Label ID="authorizationLabel" runat="server" />
+ </fieldset>
+ <br />
+ <asp:Button ID="getNameButton" runat="server" Text="Get Name" OnClick="getNameButton_Click" />
+ <asp:Label ID="nameLabel" runat="server" />
+ <br />
+ <asp:Button ID="getAgeButton" runat="server" Text="Get Age" OnClick="getAgeButton_Click" />
+ <asp:Label ID="ageLabel" runat="server" />
+ <br />
+ <asp:Button ID="getFavoriteSites" runat="server" Text="Get Favorite Sites"
+ onclick="getFavoriteSites_Click" />
+ <asp:Label ID="favoriteSitesLabel" runat="server" />
+</asp:Content> \ No newline at end of file
diff --git a/samples/OAuthConsumer/SampleWcf2.aspx.cs b/samples/OAuthConsumer/SampleWcf2.aspx.cs
new file mode 100644
index 0000000..7fae00b
--- /dev/null
+++ b/samples/OAuthConsumer/SampleWcf2.aspx.cs
@@ -0,0 +1,112 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Linq;
+ using System.Net;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Security;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuthWrap;
+ using OAuthConsumer.SampleServiceProvider;
+
+ public partial class SampleWcf2 : System.Web.UI.Page {
+ private static InMemoryClientTokenManager tokenManager = new InMemoryClientTokenManager();
+
+ private static IAuthorizationState Authorization {
+ get { return (AuthorizationState)HttpContext.Current.Session["Authorization"]; }
+ set { HttpContext.Current.Session["Authorization"] = value; }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ var client = CreateClient();
+ if (!IsPostBack) {
+ var authorization = client.ProcessUserAuthorization();
+ if (authorization != null) {
+ Authorization = authorization;
+ }
+ }
+
+ if (Authorization != null) {
+ client.RefreshToken(Authorization, TimeSpan.FromMinutes(1));
+ }
+ }
+
+ protected void getAuthorizationButton_Click(object sender, EventArgs e) {
+ string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>()
+ where item.Selected
+ select item.Value).ToArray();
+ string scope = string.Join(" ", scopes);
+
+ var client = CreateClient();
+ string clientState;
+ var response = client.PrepareRequestUserAuthorization(tokenManager.NewAuthorization(scope, out clientState));
+ response.ClientState = clientState;
+ client.Channel.Send(response);
+ }
+
+ protected void getNameButton_Click(object sender, EventArgs e) {
+ try {
+ this.nameLabel.Text = CallService(client => client.GetName());
+ } catch (SecurityAccessDeniedException) {
+ this.nameLabel.Text = "Access denied!";
+ }
+ }
+
+ protected void getAgeButton_Click(object sender, EventArgs e) {
+ try {
+ int? age = CallService(client => client.GetAge());
+ this.ageLabel.Text = age.HasValue ? age.Value.ToString(CultureInfo.CurrentCulture) : "not available";
+ } catch (SecurityAccessDeniedException) {
+ this.ageLabel.Text = "Access denied!";
+ }
+ }
+
+ protected void getFavoriteSites_Click(object sender, EventArgs e) {
+ try {
+ string[] favoriteSites = CallService(client => client.GetFavoriteSites());
+ this.favoriteSitesLabel.Text = string.Join(", ", favoriteSites);
+ } catch (SecurityAccessDeniedException) {
+ this.favoriteSitesLabel.Text = "Access denied!";
+ }
+ }
+
+ private static WebServerClient CreateClient() {
+ var authServerDescription = new AuthorizationServerDescription {
+ TokenEndpoint = new Uri("http://localhost:65169/OAuth2.ashx/token"),
+ AuthorizationEndpoint = new Uri("http://localhost:65169/OAuth2.ashx/auth"),
+ };
+
+ var client = new WebServerClient(authServerDescription) {
+ ClientIdentifier = "sampleconsumer",
+ ClientSecret = "samplesecret",
+ TokenManager = tokenManager,
+ };
+
+ return client;
+ }
+
+ private T CallService<T>(Func<DataApiClient, T> predicate) {
+ DataApiClient client = new DataApiClient();
+ ////var serviceEndpoint = new MessageReceivingEndpoint(client.Endpoint.Address.Uri, HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest);
+ if (Authorization == null) {
+ throw new InvalidOperationException("No access token!");
+ }
+
+ var httpRequest = (HttpWebRequest)WebRequest.Create(client.Endpoint.Address.Uri);
+ var oauthClient = CreateClient();
+ oauthClient.AuthorizeRequest(httpRequest, Authorization.AccessToken);
+
+ var httpDetails = new HttpRequestMessageProperty();
+ httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization];
+ using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) {
+ OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpDetails;
+ return predicate(client);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OAuthConsumer/SampleWcf2.aspx.designer.cs b/samples/OAuthConsumer/SampleWcf2.aspx.designer.cs
new file mode 100644
index 0000000..f42efff
--- /dev/null
+++ b/samples/OAuthConsumer/SampleWcf2.aspx.designer.cs
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class SampleWcf2 {
+
+ /// <summary>
+ /// scopeList control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CheckBoxList scopeList;
+
+ /// <summary>
+ /// getAuthorizationButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAuthorizationButton;
+
+ /// <summary>
+ /// authorizationLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label authorizationLabel;
+
+ /// <summary>
+ /// getNameButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getNameButton;
+
+ /// <summary>
+ /// nameLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label nameLabel;
+
+ /// <summary>
+ /// getAgeButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAgeButton;
+
+ /// <summary>
+ /// ageLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label ageLabel;
+
+ /// <summary>
+ /// getFavoriteSites control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getFavoriteSites;
+
+ /// <summary>
+ /// favoriteSitesLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label favoriteSitesLabel;
+ }
+}
diff --git a/samples/OAuthConsumer/Web.config b/samples/OAuthConsumer/Web.config
index 7753874..20c5822 100644
--- a/samples/OAuthConsumer/Web.config
+++ b/samples/OAuthConsumer/Web.config
@@ -39,6 +39,9 @@
<dotNetOpenAuth>
<!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
<reporting enabled="true" />
+
+ <!-- FOR TESTING ONLY, we relax the SSL requirements. -->
+ <messaging relaxSslRequirements="true" />
</dotNetOpenAuth>
<appSettings>
@@ -48,8 +51,13 @@
<add key="twitterConsumerKey" value="" />
<add key="twitterConsumerSecret" value="" />
<!-- Google sign-up: https://www.google.com/accounts/ManageDomains -->
+ <add key="googleConsumerKey" value=""/>
+ <add key="googleConsumerSecret" value=""/>
<add key="googleConsumerKey" value="anonymous"/>
<add key="googleConsumerSecret" value="anonymous"/>
+ <!-- Facebook sign-up: http://developers.facebook.com/setup/ -->
+ <add key="facebookAppID" value="367207604173"/>
+ <add key="facebookAppSecret" value="1df77e64055c4d7d3583cefdf2bc62d7"/>
</appSettings>
<connectionStrings/>
diff --git a/samples/OAuthConsumerWpf/Authorize2.xaml b/samples/OAuthConsumerWpf/Authorize2.xaml
new file mode 100644
index 0000000..ea5047f
--- /dev/null
+++ b/samples/OAuthConsumerWpf/Authorize2.xaml
@@ -0,0 +1,11 @@
+<Window x:Class="DotNetOpenAuth.Samples.OAuthConsumerWpf.Authorize2"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ Title="Authorize" Height="500" Width="500">
+ <DockPanel LastChildFill="True">
+ <WindowsFormsHost Name="windowsFormsHost1">
+ <wf:WebBrowser x:Name="webBrowser" Dock="Fill" Navigating="webBrowser_Navigating" Navigated="webBrowser_Navigated" LocationChanged="webBrowser_LocationChanged" />
+ </WindowsFormsHost>
+ </DockPanel>
+</Window>
diff --git a/samples/OAuthConsumerWpf/Authorize2.xaml.cs b/samples/OAuthConsumerWpf/Authorize2.xaml.cs
new file mode 100644
index 0000000..91435da
--- /dev/null
+++ b/samples/OAuthConsumerWpf/Authorize2.xaml.cs
@@ -0,0 +1,56 @@
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using System.Text;
+ using System.Windows;
+ using System.Windows.Controls;
+ using System.Windows.Data;
+ using System.Windows.Documents;
+ using System.Windows.Input;
+ using System.Windows.Media;
+ using System.Windows.Media.Imaging;
+ using System.Windows.Navigation;
+ using System.Windows.Shapes;
+ using DotNetOpenAuth.OAuthWrap;
+
+ /// <summary>
+ /// Interaction logic for Authorize2.xaml
+ /// </summary>
+ public partial class Authorize2 : Window {
+ private UserAgentClient client;
+
+ internal Authorize2(UserAgentClient client) {
+ Contract.Requires(client != null, "client");
+
+ InitializeComponent();
+
+ this.client = client;
+ this.Authorization = new AuthorizationState();
+ this.webBrowser.Navigate(this.client.RequestUserAuthorization(this.Authorization));
+ }
+
+ public IAuthorizationState Authorization { get; set; }
+
+ private void webBrowser_Navigating(object sender, System.Windows.Forms.WebBrowserNavigatingEventArgs e) {
+ this.locationChanged(e.Url);
+ }
+
+ private void locationChanged(Uri location) {
+ if (location == this.Authorization.Callback) {
+ this.client.ProcessUserAuthorization(location, this.Authorization);
+ this.DialogResult = !string.IsNullOrEmpty(this.Authorization.AccessToken);
+ this.Close();
+ }
+ }
+
+ private void webBrowser_Navigated(object sender, System.Windows.Forms.WebBrowserNavigatedEventArgs e) {
+ this.locationChanged(e.Url);
+ }
+
+ private void webBrowser_LocationChanged(object sender, EventArgs e) {
+ this.locationChanged(webBrowser.Url);
+ }
+ }
+}
diff --git a/samples/OAuthConsumerWpf/MainWindow.xaml b/samples/OAuthConsumerWpf/MainWindow.xaml
index c59175c..05370d7 100644
--- a/samples/OAuthConsumerWpf/MainWindow.xaml
+++ b/samples/OAuthConsumerWpf/MainWindow.xaml
@@ -2,136 +2,194 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DotNetOpenAuth Consumer (sample)" Height="400" Width="442">
- <TabControl Name="outerTabControl" Margin="0,10,0,0">
- <TabItem Header="Google" Name="googleTab">
- <Grid Margin="5">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition />
- </Grid.RowDefinitions>
- <Button Grid.Column="1" Grid.Row="3" Name="beginAuthorizationButton" Click="beginAuthorizationButton_Click">Authorize</Button>
- <TabControl Grid.ColumnSpan="2" Grid.Row="4" Name="tabControl1" Margin="0,10,0,0">
- <TabItem Header="Gmail Contacts" Name="gmailContactsTab">
- <Grid Name="contactsGrid">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- </Grid>
- </TabItem>
- <TabItem Header="Blogger" Name="bloggerTab">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Label>Blog URL</Label>
- <TextBox Grid.Column="1" x:Name="blogUrlBox"/>
- <Label Grid.Row="1">Title</Label>
- <TextBox Grid.Row="1" Grid.Column="1" x:Name="postTitleBox">OAuth Rocks!</TextBox>
- <Label Grid.Row="2">Body</Label>
- <TextBox Grid.Row="2" Grid.Column="1" x:Name="postBodyBox" AcceptsReturn="True" AcceptsTab="True" AutoWordSelection="True" TextWrapping="WrapWithOverflow">&lt;p xmlns="http://www.w3.org/1999/xhtml"&gt;Oauth is cool&lt;/p&gt;</TextBox>
- <Button x:Name="postButton" Grid.Row="3" Grid.Column="1" Click="postButton_Click" IsEnabled="False">Post</Button>
- </Grid>
- </TabItem>
- </TabControl>
- </Grid>
- </TabItem>
- <TabItem Header="WCF sample">
- <Grid Margin="5">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition />
- </Grid.RowDefinitions>
- <Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Name="beginWcfAuthorizationButton" Click="beginWcfAuthorizationButton_Click">Authorize</Button>
- <Label Content="Name" Grid.Row="1" />
- <Label Grid.Row="1" Grid.Column="1" Name="wcfName" />
- <Label Content="Age" Grid.Row="2" />
- <Label Grid.Row="2" Grid.Column="1" Name="wcfAge" />
- <Label Content="Favorite sites" Grid.Row="3" />
- <Label Grid.Row="3" Grid.Column="1" Name="wcfFavoriteSites" />
- </Grid>
- </TabItem>
- <TabItem Header="Generic">
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="auto" />
- <RowDefinition Height="auto" />
- <RowDefinition Height="auto" />
- <RowDefinition Height="auto" />
- <RowDefinition Height="auto" />
- <RowDefinition Height="auto" />
- <RowDefinition Height="auto" />
- <RowDefinition Height="auto" />
- <RowDefinition Height="*" />
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="auto" />
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="auto" />
- </Grid.ColumnDefinitions>
- <Label Grid.Row="0">Request Token URL</Label>
- <TextBox Grid.Column="1" x:Name="requestTokenUrlBox" />
- <ComboBox Grid.Column="2" x:Name="requestTokenHttpMethod" SelectedIndex="1">
- <ComboBox.Items>
- <ComboBoxItem>GET</ComboBoxItem>
- <ComboBoxItem>POST</ComboBoxItem>
- </ComboBox.Items>
- </ComboBox>
- <Label Grid.Row="1">Authorize URL</Label>
- <TextBox Grid.Row="1" Grid.Column="1" x:Name="authorizeUrlBox" />
- <Label Grid.Row="1" Grid.Column="2">GET</Label>
- <Label Grid.Row="2">Access Token URL</Label>
- <TextBox Grid.Row="2" Grid.Column="1" x:Name="accessTokenUrlBox" />
- <ComboBox Grid.Row="2" Grid.Column="2" x:Name="accessTokenHttpMethod" SelectedIndex="1">
- <ComboBox.Items>
- <ComboBoxItem>GET</ComboBoxItem>
- <ComboBoxItem>POST</ComboBoxItem>
- </ComboBox.Items>
- </ComboBox>
- <Label Grid.Row="3">Resource URL</Label>
- <TextBox Grid.Row="3" Grid.Column="1" x:Name="resourceUrlBox" />
- <ComboBox Grid.Row="3" Grid.Column="2" x:Name="resourceHttpMethodList" SelectedIndex="0">
- <ComboBox.Items>
- <ComboBoxItem>GET w/ header</ComboBoxItem>
- <ComboBoxItem>GET w/ querystring</ComboBoxItem>
- <ComboBoxItem>POST</ComboBoxItem>
- </ComboBox.Items>
- </ComboBox>
- <Label Grid.Row="4">Consumer key</Label>
- <TextBox Grid.Row="4" Grid.Column="1" x:Name="consumerKeyBox" Grid.ColumnSpan="2"/>
- <Label Grid.Row="5">Consumer secret</Label>
- <TextBox Grid.Row="5" Grid.Column="1" x:Name="consumerSecretBox" Grid.ColumnSpan="2"/>
- <Label Grid.Row="6">OAuth version</Label>
- <ComboBox Grid.Row="6" Grid.Column="1" SelectedIndex="1" x:Name="oauthVersion">
- <ComboBox.Items>
- <ComboBoxItem>1.0</ComboBoxItem>
- <ComboBoxItem>1.0a</ComboBoxItem>
- </ComboBox.Items>
- </ComboBox>
- <Button Grid.Row="7" Grid.Column="1" x:Name="beginButton" Click="beginButton_Click">Begin</Button>
- <TextBox Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="3" Name="resultsBox" IsReadOnly="True" />
- </Grid>
- </TabItem>
- </TabControl>
+ <TabControl Name="outerTabControl" Margin="0,10,0,0">
+ <TabItem Header="Google" Name="googleTab">
+ <Grid Margin="5">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <Button Grid.Column="1" Grid.Row="3" Name="beginAuthorizationButton" Click="beginAuthorizationButton_Click">Authorize</Button>
+ <TabControl Grid.ColumnSpan="2" Grid.Row="4" Name="tabControl1" Margin="0,10,0,0">
+ <TabItem Header="Gmail Contacts" Name="gmailContactsTab">
+ <Grid Name="contactsGrid">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ </Grid>
+ </TabItem>
+ <TabItem Header="Blogger" Name="bloggerTab">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Label>Blog URL</Label>
+ <TextBox Grid.Column="1" x:Name="blogUrlBox"/>
+ <Label Grid.Row="1">Title</Label>
+ <TextBox Grid.Row="1" Grid.Column="1" x:Name="postTitleBox">OAuth Rocks!</TextBox>
+ <Label Grid.Row="2">Body</Label>
+ <TextBox Grid.Row="2" Grid.Column="1" x:Name="postBodyBox" AcceptsReturn="True" AcceptsTab="True" AutoWordSelection="True" TextWrapping="WrapWithOverflow">&lt;p xmlns="http://www.w3.org/1999/xhtml"&gt;Oauth is cool&lt;/p&gt;</TextBox>
+ <Button x:Name="postButton" Grid.Row="3" Grid.Column="1" Click="postButton_Click" IsEnabled="False">Post</Button>
+ </Grid>
+ </TabItem>
+ </TabControl>
+ </Grid>
+ </TabItem>
+ <TabItem Header="WCF sample">
+ <Grid Margin="5">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Name="beginWcfAuthorizationButton" Click="beginWcfAuthorizationButton_Click">Authorize</Button>
+ <Label Content="Name" Grid.Row="1" />
+ <Label Grid.Row="1" Grid.Column="1" Name="wcfName" />
+ <Label Content="Age" Grid.Row="2" />
+ <Label Grid.Row="2" Grid.Column="1" Name="wcfAge" />
+ <Label Content="Favorite sites" Grid.Row="3" />
+ <Label Grid.Row="3" Grid.Column="1" Name="wcfFavoriteSites" />
+ </Grid>
+ </TabItem>
+ <TabItem Header="Generic 1.0(a)">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="auto" />
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="auto" />
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="0">Request Token URL</Label>
+ <TextBox Grid.Column="1" x:Name="requestTokenUrlBox" />
+ <ComboBox Grid.Column="2" x:Name="requestTokenHttpMethod" SelectedIndex="1">
+ <ComboBox.Items>
+ <ComboBoxItem>GET</ComboBoxItem>
+ <ComboBoxItem>POST</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="1">Authorize URL</Label>
+ <TextBox Grid.Row="1" Grid.Column="1" x:Name="authorizeUrlBox" />
+ <Label Grid.Row="1" Grid.Column="2">GET</Label>
+ <Label Grid.Row="2">Access Token URL</Label>
+ <TextBox Grid.Row="2" Grid.Column="1" x:Name="accessTokenUrlBox" />
+ <ComboBox Grid.Row="2" Grid.Column="2" x:Name="accessTokenHttpMethod" SelectedIndex="1">
+ <ComboBox.Items>
+ <ComboBoxItem>GET</ComboBoxItem>
+ <ComboBoxItem>POST</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="3">Resource URL</Label>
+ <TextBox Grid.Row="3" Grid.Column="1" x:Name="resourceUrlBox" />
+ <ComboBox Grid.Row="3" Grid.Column="2" x:Name="resourceHttpMethodList" SelectedIndex="0">
+ <ComboBox.Items>
+ <ComboBoxItem>GET w/ header</ComboBoxItem>
+ <ComboBoxItem>GET w/ querystring</ComboBoxItem>
+ <ComboBoxItem>POST</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="4">Consumer key</Label>
+ <TextBox Grid.Row="4" Grid.Column="1" x:Name="consumerKeyBox" Grid.ColumnSpan="2"/>
+ <Label Grid.Row="5">Consumer secret</Label>
+ <TextBox Grid.Row="5" Grid.Column="1" x:Name="consumerSecretBox" Grid.ColumnSpan="2"/>
+ <Label Grid.Row="6">OAuth version</Label>
+ <ComboBox Grid.Row="6" Grid.Column="1" SelectedIndex="1" x:Name="oauthVersion">
+ <ComboBox.Items>
+ <ComboBoxItem>1.0</ComboBoxItem>
+ <ComboBoxItem>1.0a</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Button Grid.Row="7" Grid.Column="1" x:Name="beginButton" Click="beginButton_Click">Begin</Button>
+ <TextBox Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="3" Name="resultsBox" IsReadOnly="True" />
+ </Grid>
+ </TabItem>
+ <TabItem Header="Generic 2.0">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="auto" />
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="auto" />
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="1">Token Endpoint URL</Label>
+ <TextBox Grid.Row="1" Grid.Column="1" x:Name="wrapTokenUrlBox" />
+ <Label Grid.Row="1" Grid.Column="2">POST</Label>
+ <Label Grid.Row="2">User Authorization URL</Label>
+ <TextBox Grid.Row="2" Grid.Column="1" x:Name="wrapAuthorizationUrlBox" Text="https://graph.facebook.com/oauth/authorize?display=popup" />
+ <Label Grid.Row="2" Grid.Column="2">GET</Label>
+ <Label Grid.Row="0">Flow</Label>
+ <ComboBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" x:Name="flowBox" SelectedIndex="1">
+ <ComboBox.Items>
+ <ComboBoxItem>Web Server</ComboBoxItem>
+ <ComboBoxItem>User Agent</ComboBoxItem>
+ <ComboBoxItem>Device</ComboBoxItem>
+ <ComboBoxItem>Username and Password</ComboBoxItem>
+ <ComboBoxItem>Assertion</ComboBoxItem>
+ <ComboBoxItem>Client Credentials</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="3">Resource URL</Label>
+ <TextBox Grid.Row="3" Grid.Column="1" x:Name="wrapResourceUrlBox" Text="https://graph.facebook.com/me" />
+ <ComboBox Grid.Row="3" Grid.Column="2" x:Name="wrapResourceHttpMethodList" SelectedIndex="0">
+ <ComboBox.Items>
+ <ComboBoxItem>GET w/ header</ComboBoxItem>
+ <ComboBoxItem>GET w/ querystring</ComboBoxItem>
+ <ComboBoxItem>POST</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="4">Client Identifier</Label>
+ <TextBox Grid.Row="4" Grid.Column="1" x:Name="wrapClientIdentifierBox" Grid.ColumnSpan="2" Text="367207604173" />
+ <Label Grid.Row="5">Client Secret</Label>
+ <TextBox Grid.Row="5" Grid.Column="1" x:Name="wrapClientSecretBox" Grid.ColumnSpan="2"/>
+ <Label Grid.Row="6">OAuth 2.0 version</Label>
+ <ComboBox Grid.Row="6" Grid.Column="1" SelectedIndex="0" x:Name="wrapVersion">
+ <ComboBox.Items>
+ <ComboBoxItem>2.0 DRAFT 5</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Button Grid.Row="7" Grid.Column="1" x:Name="wrapBeginButton" Click="wrapBeginButton_Click">Begin</Button>
+ <TextBox Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="3" Name="wrapResultsBox" IsReadOnly="True" />
+ </Grid>
+ </TabItem>
+ </TabControl>
</Window>
diff --git a/samples/OAuthConsumerWpf/MainWindow.xaml.cs b/samples/OAuthConsumerWpf/MainWindow.xaml.cs
index 5bf157b..749a626 100644
--- a/samples/OAuthConsumerWpf/MainWindow.xaml.cs
+++ b/samples/OAuthConsumerWpf/MainWindow.xaml.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
+ using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
@@ -28,6 +29,7 @@
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;
using DotNetOpenAuth.Samples.OAuthConsumerWpf.WcfSampleService;
+ using OAuth2 = DotNetOpenAuth.OAuthWrap;
/// <summary>
/// Interaction logic for MainWindow.xaml
@@ -198,5 +200,46 @@
MessageBox.Show(this, ex.Message);
}
}
+
+ private void wrapBeginButton_Click(object sender, RoutedEventArgs e) {
+ var authServer = new DotNetOpenAuth.OAuthWrap.AuthorizationServerDescription {
+ AuthorizationEndpoint = new Uri(wrapAuthorizationUrlBox.Text),
+ };
+ if (wrapTokenUrlBox.Text.Length > 0) {
+ authServer.TokenEndpoint = new Uri(wrapTokenUrlBox.Text);
+ }
+
+ try {
+ ////var client = new DotNetOpenAuth.OAuthWrap.WebAppClient(authServer);
+ ////client.PrepareRequestUserAuthorization();
+ var client = new OAuth2.UserAgentClient(authServer) {
+ ClientIdentifier = wrapClientIdentifierBox.Text,
+ };
+
+ var authorizePopup = new Authorize2(client);
+ authorizePopup.Owner = this;
+ bool? result = authorizePopup.ShowDialog();
+ if (result.HasValue && result.Value) {
+ // One method of OAuth authorization is to tack the ?access_token= onto the query string.
+ var address = new Uri(wrapResourceUrlBox.Text);
+ address = new Uri(wrapResourceUrlBox.Text + (string.IsNullOrEmpty(address.Query) ? "?" : string.Empty) + "access_token=" + Uri.EscapeDataString(authorizePopup.Authorization.AccessToken));
+ var request = (HttpWebRequest)WebRequest.Create(address);
+
+ // This method tacks on the Authorization header
+ client.AuthorizeRequest(request, authorizePopup.Authorization);
+
+ request.Method = wrapResourceHttpMethodList.SelectedIndex < 2 ? "GET" : "POST";
+ using (var resourceResponse = request.GetResponse()) {
+ using (var responseStream = new StreamReader(resourceResponse.GetResponseStream())) {
+ wrapResultsBox.Text = responseStream.ReadToEnd();
+ }
+ }
+ } else {
+ return;
+ }
+ } catch (DotNetOpenAuth.Messaging.ProtocolException ex) {
+ MessageBox.Show(this, ex.Message);
+ }
+ }
}
}
diff --git a/samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj b/samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj
index cdb95aa..9a26bd6 100644
--- a/samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj
+++ b/samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj
@@ -94,6 +94,8 @@
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
+ <Reference Include="WindowsFormsIntegration" />
+ <Reference Include="System.Windows.Forms" />
<Reference Include="UIAutomationProvider">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
@@ -123,6 +125,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Page Include="Authorize2.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -133,6 +139,9 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Authorize2.xaml.cs">
+ <DependentUpon>Authorize2.xaml</DependentUpon>
+ </Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
@@ -232,4 +241,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project> \ No newline at end of file
+</Project>
diff --git a/samples/OAuthServiceProvider/Code/Global.cs b/samples/OAuthServiceProvider/Code/Global.cs
index ceaeac8..fd7d475 100644
--- a/samples/OAuthServiceProvider/Code/Global.cs
+++ b/samples/OAuthServiceProvider/Code/Global.cs
@@ -5,6 +5,8 @@
using System.Text;
using System.Web;
using DotNetOpenAuth.OAuth.Messages;
+ using DotNetOpenAuth.OAuthWrap;
+ using DotNetOpenAuth.OAuthWrap.Messages;
/// <summary>
/// The web application global events and properties.
@@ -20,6 +22,8 @@
/// </summary>
public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthServiceProvider");
+ public static WebServerAuthorizationServer AuthorizationServer = new WebServerAuthorizationServer(new OAuth2AuthorizationServer());
+
/// <summary>
/// Gets the transaction-protected database connection for the current request.
/// </summary>
@@ -50,6 +54,12 @@
set { HttpContext.Current.Session["authrequest"] = value; }
}
+ public static WebServerRequest PendingOAuth2Authorization
+ {
+ get { return HttpContext.Current.Session["authrequest"] as WebServerRequest; }
+ set { HttpContext.Current.Session["authrequest"] = value; }
+ }
+
private static DataClassesDataContext dataContextSimple {
get {
if (HttpContext.Current != null) {
diff --git a/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs
new file mode 100644
index 0000000..e281b07
--- /dev/null
+++ b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs
@@ -0,0 +1,60 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.Web;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuthWrap;
+ using DotNetOpenAuth.OAuthWrap.ChannelElements;
+
+ internal class OAuth2AuthorizationServer : IAuthorizationServer {
+ internal static readonly RSAParameters AsymmetricKey;
+
+ private static readonly byte[] secret;
+
+ private readonly INonceStore nonceStore = new DatabaseNonceStore();
+
+ static OAuth2AuthorizationServer() {
+ // For this sample, we just generate random secrets.
+ RandomNumberGenerator crypto = new RNGCryptoServiceProvider();
+ secret = new byte[16];
+ crypto.GetBytes(secret);
+
+ AsymmetricKey = new RSACryptoServiceProvider().ExportParameters(true);
+ }
+
+ #region Implementation of IAuthorizationServer
+
+ public byte[] Secret {
+ get { return secret; }
+ }
+
+ public DotNetOpenAuth.Messaging.Bindings.INonceStore VerificationCodeNonceStore {
+ get { return this.nonceStore; }
+ }
+
+ public RSAParameters AccessTokenSigningPrivateKey {
+ get { return AsymmetricKey; }
+ }
+
+ public IConsumerDescription GetClient(string clientIdentifier) {
+ var consumerRow = Global.DataContext.OAuthConsumers.SingleOrDefault(
+ consumerCandidate => consumerCandidate.ConsumerKey == clientIdentifier);
+ if (consumerRow == null) {
+ throw new ArgumentOutOfRangeException("clientIdentifier");
+ }
+
+ return consumerRow;
+ }
+
+ #endregion
+
+ public bool IsAuthorizationValid(IAuthorizationDescription authorization) {
+ // We don't support revoking tokens yet.
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs b/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
index 6d5bfff..92038bd 100644
--- a/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
+++ b/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
@@ -7,8 +7,9 @@
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
- using DotNetOpenAuth;
using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuthWrap;
/// <summary>
/// A WCF extension to authenticate incoming messages using OAuth.
@@ -24,17 +25,14 @@
HttpRequestMessageProperty httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
Uri requestUri = operationContext.RequestContext.RequestMessage.Properties["OriginalHttpRequestUri"] as Uri;
- ServiceProvider sp = Constants.CreateServiceProvider();
- try {
- var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
- if (auth != null) {
- var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
- var principal = sp.CreatePrincipal(auth);
+ try {
+ var principal = this.VerifyOAuth2(httpDetails, requestUri);
+ if (principal != null) {
var policy = new OAuthPrincipalAuthorizationPolicy(principal);
var policies = new List<IAuthorizationPolicy> {
- policy,
- };
+ policy,
+ };
var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
if (operationContext.IncomingMessageProperties.Security != null) {
@@ -46,14 +44,13 @@
}
securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
- principal.Identity,
- };
+ principal.Identity,
+ };
// Only allow this method call if the access token scope permits it.
- string[] scopes = accessToken.Scope.Split('|');
- if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
- return true;
- }
+ return principal.IsInRole(operationContext.IncomingMessageHeaders.Action);
+ } else {
+ return false;
}
} catch (ProtocolException ex) {
Global.Logger.Error("Error processing OAuth messages.", ex);
@@ -61,5 +58,36 @@
return false;
}
+
+ private OAuthPrincipal VerifyOAuth1(HttpRequestMessageProperty httpDetails, Uri requestUri) {
+ ServiceProvider sp = Constants.CreateServiceProvider();
+ var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
+ if (auth != null) {
+ var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
+ var principal = sp.CreatePrincipal(auth);
+ return principal;
+ }
+
+ return null;
+ }
+
+ private OAuthPrincipal VerifyOAuth2(HttpRequestMessageProperty httpDetails, Uri requestUri) {
+ // for this sample where the auth server and resource server are the same site,
+ // we use the same public/private key.
+ var resourceServer = new ResourceServer(
+ new StandardAccessTokenAnalyzer(
+ OAuth2AuthorizationServer.AsymmetricKey,
+ OAuth2AuthorizationServer.AsymmetricKey));
+
+ string username, scope;
+ var error = resourceServer.VerifyAccess(new DotNetOpenAuth.Messaging.HttpRequestInfo(httpDetails, requestUri), out username, out scope);
+ if (error == null) {
+ string[] scopes = scope.Split(new char[] { ' ' });
+ var principal = new OAuthPrincipal(username, scopes);
+ return principal;
+ } else {
+ return null;
+ }
+ }
}
} \ No newline at end of file
diff --git a/samples/OAuthServiceProvider/Members/Authorize.aspx b/samples/OAuthServiceProvider/Members/Authorize.aspx
index b3e2c6a..251189a 100644
--- a/samples/OAuthServiceProvider/Members/Authorize.aspx
+++ b/samples/OAuthServiceProvider/Members/Authorize.aspx
@@ -1,4 +1,4 @@
-<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthServiceProvider.Authorize" Codebehind="Authorize.aspx.cs" %>
+<%@ Page Title="Authorize Access" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthServiceProvider.Authorize" Codebehind="Authorize.aspx.cs" %>
<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
<asp:MultiView runat="server" ActiveViewIndex="0" ID="multiView">
diff --git a/samples/OAuthServiceProvider/Members/Authorize2.aspx b/samples/OAuthServiceProvider/Members/Authorize2.aspx
new file mode 100644
index 0000000..eb8322f
--- /dev/null
+++ b/samples/OAuthServiceProvider/Members/Authorize2.aspx
@@ -0,0 +1,53 @@
+<%@ Page Title="Authorize Access" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
+ CodeBehind="Authorize2.aspx.cs" Inherits="OAuthServiceProvider.Members.Authorize2" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="server">
+ <asp:MultiView runat="server" ActiveViewIndex="0" ID="multiView">
+ <asp:View ID="AuthRequest" runat="server">
+ <div style="background-color: Yellow">
+ <b>Warning</b>: Never give your login credentials to another web site or application.
+ </div>
+ <asp:HiddenField runat="server" ID="OAuthAuthorizationSecToken" EnableViewState="false" />
+ <p>The client web site or application <asp:Label ID="consumerLabel" Font-Bold="true"
+ runat="server" Text="[consumer]" /> wants access to your <asp:Label ID="desiredAccessLabel"
+ Font-Bold="true" runat="server" Text="[protected resource]" />. </p>
+ <p>Do you want to allow this? </p>
+ <div style="display: none" id="responseButtonsDiv">
+ <asp:Button ID="allowAccessButton" runat="server" Text="Yes" OnClick="allowAccessButton_Click" />
+ <asp:Button ID="denyAccessButton" runat="server" Text="No" OnClick="denyAccessButton_Click" />
+ </div>
+ <div id="javascriptDisabled">
+ <b>JavaScript appears to be disabled in your browser. </b>This page requires Javascript
+ to be enabled to better protect your security.
+ </div>
+ <p>If you grant access now, you can revoke it at any time by returning to this page.
+ </p>
+ <script language="javascript" type="text/javascript">
+ //<![CDATA[
+ // we use HTML to hide the action buttons and JavaScript to show them
+ // to protect against click-jacking in an iframe whose JavaScript is disabled.
+ document.getElementById('responseButtonsDiv').style.display = 'block';
+ document.getElementById('javascriptDisabled').style.display = 'none';
+
+ // Frame busting code (to protect us from being hosted in an iframe).
+ // This protects us from click-jacking.
+ if (document.location !== window.top.location) {
+ window.top.location = document.location;
+ }
+ //]]>
+ </script>
+ </asp:View>
+ <asp:View ID="AuthGranted" runat="server">
+ <p>Authorization has been granted.</p>
+ <asp:MultiView runat="server" ID="verifierMultiView" ActiveViewIndex="0">
+ <asp:View ID="View3" runat="server">
+ <p>You must enter this verification code at the Consumer: <asp:Label runat="server"
+ ID="verificationCodeLabel" /> </p>
+ </asp:View>
+ <asp:View ID="View4" runat="server">
+ <p>You may now close this window and return to the Consumer. </p>
+ </asp:View>
+ </asp:MultiView>
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/samples/OAuthServiceProvider/Members/Authorize2.aspx.cs b/samples/OAuthServiceProvider/Members/Authorize2.aspx.cs
new file mode 100644
index 0000000..0c14bfd
--- /dev/null
+++ b/samples/OAuthServiceProvider/Members/Authorize2.aspx.cs
@@ -0,0 +1,53 @@
+namespace OAuthServiceProvider.Members {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using Code;
+
+ public partial class Authorize2 : System.Web.UI.Page {
+ private static readonly RandomNumberGenerator CryptoRandomDataGenerator = new RNGCryptoServiceProvider();
+
+ private string AuthorizationSecret {
+ get { return Session["OAuthAuthorizationSecret"] as string; }
+ set { Session["OAuthAuthorizationSecret"] = value; }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (!IsPostBack) {
+ if (Global.PendingOAuth2Authorization == null) {
+ Response.Redirect("~/Members/AuthorizedConsumers.aspx");
+ } else {
+ var pendingRequest = Global.PendingOAuth2Authorization;
+ this.desiredAccessLabel.Text = pendingRequest.Scope;
+ this.consumerLabel.Text = pendingRequest.ClientIdentifier;
+
+ // Generate an unpredictable secret that goes to the user agent and must come back
+ // with authorization to guarantee the user interacted with this page rather than
+ // being scripted by an evil Consumer.
+ var randomData = new byte[8];
+ CryptoRandomDataGenerator.GetBytes(randomData);
+ this.AuthorizationSecret = Convert.ToBase64String(randomData);
+ this.OAuthAuthorizationSecToken.Value = this.AuthorizationSecret;
+ }
+ }
+ }
+
+ protected void allowAccessButton_Click(object sender, EventArgs e) {
+ if (this.AuthorizationSecret != this.OAuthAuthorizationSecToken.Value) {
+ throw new ArgumentException(); // probably someone trying to hack in.
+ }
+ this.AuthorizationSecret = null; // clear one time use secret
+ this.multiView.SetActiveView(this.AuthGranted);
+
+ Global.AuthorizationServer.ApproveAuthorizationRequest(Global.PendingOAuth2Authorization, User.Identity.Name);
+ }
+
+ protected void denyAccessButton_Click(object sender, EventArgs e) {
+ Global.AuthorizationServer.RejectAuthorizationRequest(Global.PendingOAuth2Authorization);
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OAuthServiceProvider/Members/Authorize2.aspx.designer.cs b/samples/OAuthServiceProvider/Members/Authorize2.aspx.designer.cs
new file mode 100644
index 0000000..db39669
--- /dev/null
+++ b/samples/OAuthServiceProvider/Members/Authorize2.aspx.designer.cs
@@ -0,0 +1,123 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Members {
+
+
+ public partial class Authorize2 {
+
+ /// <summary>
+ /// multiView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView multiView;
+
+ /// <summary>
+ /// AuthRequest control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthRequest;
+
+ /// <summary>
+ /// OAuthAuthorizationSecToken control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.HiddenField OAuthAuthorizationSecToken;
+
+ /// <summary>
+ /// consumerLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label consumerLabel;
+
+ /// <summary>
+ /// desiredAccessLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label desiredAccessLabel;
+
+ /// <summary>
+ /// allowAccessButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button allowAccessButton;
+
+ /// <summary>
+ /// denyAccessButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button denyAccessButton;
+
+ /// <summary>
+ /// AuthGranted control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthGranted;
+
+ /// <summary>
+ /// verifierMultiView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView verifierMultiView;
+
+ /// <summary>
+ /// View3 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View3;
+
+ /// <summary>
+ /// verificationCodeLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label verificationCodeLabel;
+
+ /// <summary>
+ /// View4 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View4;
+ }
+}
diff --git a/samples/OAuthServiceProvider/OAuth.ashx b/samples/OAuthServiceProvider/OAuth.ashx
index 8a74926..efa8140 100644
--- a/samples/OAuthServiceProvider/OAuth.ashx
+++ b/samples/OAuthServiceProvider/OAuth.ashx
@@ -11,7 +11,7 @@ using DotNetOpenAuth.Messaging;
using OAuthServiceProvider.Code;
public class OAuth : IHttpHandler, IRequiresSessionState {
- ServiceProvider sp;
+ private ServiceProvider sp;
public OAuth() {
sp = new ServiceProvider(Constants.SelfDescription, Global.TokenManager, new CustomOAuthMessageFactory(Global.TokenManager));
diff --git a/samples/OAuthServiceProvider/OAuth2.ashx b/samples/OAuthServiceProvider/OAuth2.ashx
new file mode 100644
index 0000000..e36a105
--- /dev/null
+++ b/samples/OAuthServiceProvider/OAuth2.ashx
@@ -0,0 +1 @@
+<%@ WebHandler Language="C#" CodeBehind="OAuth2.ashx.cs" Class="OAuthServiceProvider.OAuth2" %>
diff --git a/samples/OAuthServiceProvider/OAuth2.ashx.cs b/samples/OAuthServiceProvider/OAuth2.ashx.cs
new file mode 100644
index 0000000..272502c
--- /dev/null
+++ b/samples/OAuthServiceProvider/OAuth2.ashx.cs
@@ -0,0 +1,53 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Net;
+ using System.Web;
+ using System.Web.SessionState;
+ using Code;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuthWrap;
+
+ public class OAuth2 : IHttpHandler, IRequiresSessionState {
+ /// <summary>
+ /// Gets a value indicating whether another request can use the <see cref="T:System.Web.IHttpHandler"/> instance.
+ /// </summary>
+ /// <value>Always <c>true</c></value>
+ /// <returns>true if the <see cref="T:System.Web.IHttpHandler"/> instance is reusable; otherwise, false.
+ /// </returns>
+ public bool IsReusable {
+ get { return true; }
+ }
+
+ /// <summary>
+ /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler"/> interface.
+ /// </summary>
+ /// <param name="context">An <see cref="T:System.Web.HttpContext"/> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>
+ public void ProcessRequest(HttpContext context) {
+ IDirectResponseProtocolMessage response;
+ switch (context.Request.PathInfo) {
+ case "/token":
+ if (Global.AuthorizationServer.TryPrepareAccessTokenResponse(out response)) {
+ Global.AuthorizationServer.Channel.Send(response);
+ }
+ break;
+ case "/auth":
+ var request = Global.AuthorizationServer.ReadAuthorizationRequest();
+ if (request == null) {
+ throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
+ }
+
+ // This sample doesn't implement support for immediate mode.
+ if (!request.IsUserInteractionAllowed) {
+ Global.AuthorizationServer.RejectAuthorizationRequest(request);
+ }
+
+ // Redirect the user to a page that requires the user to be logged in.
+ Global.PendingOAuth2Authorization = request;
+ context.Response.Redirect("~/Members/Authorize2.aspx");
+ break;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OAuthServiceProvider/OAuthServiceProvider.csproj b/samples/OAuthServiceProvider/OAuthServiceProvider.csproj
index 68b2d90..c31e8bf 100644
--- a/samples/OAuthServiceProvider/OAuthServiceProvider.csproj
+++ b/samples/OAuthServiceProvider/OAuthServiceProvider.csproj
@@ -59,6 +59,7 @@
<Content Include="Global.asax" />
<Content Include="Login.aspx" />
<Content Include="Members\Authorize.aspx" />
+ <Content Include="Members\Authorize2.aspx" />
<Content Include="Members\AuthorizedConsumers.aspx" />
<Content Include="Members\Logoff.aspx" />
<Content Include="TracePage.aspx" />
@@ -66,9 +67,20 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Code\DatabaseNonceStore.cs" />
+ <Compile Include="Code\OAuth2AuthorizationServer.cs" />
<Compile Include="Default.aspx.designer.cs">
<DependentUpon>Default.aspx</DependentUpon>
</Compile>
+ <Compile Include="Members\Authorize2.aspx.cs">
+ <DependentUpon>Authorize2.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Members\Authorize2.aspx.designer.cs">
+ <DependentUpon>Authorize2.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="OAuth2.ashx.cs">
+ <DependentUpon>OAuth2.ashx</DependentUpon>
+ </Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DataApi.cs">
<DependentUpon>DataApi.svc</DependentUpon>
@@ -133,6 +145,7 @@
<SubType>Designer</SubType>
</None>
<Content Include="Members\Web.config" />
+ <Content Include="OAuth2.ashx" />
</ItemGroup>
<ItemGroup>
<None Include="Code\DataClasses.dbml.layout">
diff --git a/samples/OAuthServiceProvider/Web.config b/samples/OAuthServiceProvider/Web.config
index dc440fd..76f2232 100644
--- a/samples/OAuthServiceProvider/Web.config
+++ b/samples/OAuthServiceProvider/Web.config
@@ -39,11 +39,14 @@
<dotNetOpenAuth>
<!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
<reporting enabled="true" />
+
+ <!-- FOR TESTING ONLY, we relax the SSL requirements. -->
+ <messaging relaxSslRequirements="true" />
</dotNetOpenAuth>
<appSettings/>
<connectionStrings>
- <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True"
+ <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database3.mdf;Integrated Security=True;User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>