diff options
Diffstat (limited to 'samples')
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"><p xmlns="http://www.w3.org/1999/xhtml">Oauth is cool</p></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"><p xmlns="http://www.w3.org/1999/xhtml">Oauth is cool</p></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> |