diff options
Diffstat (limited to 'samples/OAuthConsumer')
-rw-r--r-- | samples/OAuthConsumer/Default.aspx | 1 | ||||
-rw-r--r-- | samples/OAuthConsumer/Facebook.aspx | 16 | ||||
-rw-r--r-- | samples/OAuthConsumer/Facebook.aspx.cs | 32 | ||||
-rw-r--r-- | samples/OAuthConsumer/Facebook.aspx.designer.cs | 33 | ||||
-rw-r--r-- | samples/OAuthConsumer/OAuthConsumer.csproj | 16 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf.aspx | 2 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf.aspx.cs | 8 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf2.aspx | 23 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf2.aspx.cs | 119 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf2.aspx.designer.cs | 96 | ||||
-rw-r--r-- | samples/OAuthConsumer/Web.config | 8 |
11 files changed, 349 insertions, 5 deletions
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..95e209a --- /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.OAuth2; + + 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 284b8e9..698de7a 100644 --- a/samples/OAuthConsumer/OAuthConsumer.csproj +++ b/samples/OAuthConsumer/OAuthConsumer.csproj @@ -58,6 +58,7 @@ </ItemGroup> <ItemGroup> <Content Include="Default.aspx" /> + <Content Include="Facebook.aspx" /> <Content Include="favicon.ico" /> <Content Include="Global.asax" /> <Content Include="GoogleAddressBook.aspx" /> @@ -71,6 +72,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" /> @@ -86,6 +88,13 @@ <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> @@ -99,6 +108,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..deef073 --- /dev/null +++ b/samples/OAuthConsumer/SampleWcf2.aspx.cs @@ -0,0 +1,119 @@ +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.OAuth2; + + using OAuthConsumer.SampleServiceProvider; + + public partial class SampleWcf2 : System.Web.UI.Page { + /// <summary> + /// The details about the sample OAuth-enabled WCF service that this sample client calls into. + /// </summary> + private static AuthorizationServerDescription AuthServerDescription = new AuthorizationServerDescription { + TokenEndpoint = new Uri("http://localhost:65169/OAuth2.ashx/token"), + AuthorizationEndpoint = new Uri("http://localhost:65169/OAuth2.ashx/auth"), + }; + + /// <summary> + /// Gets or sets the authorization details for the logged in user. + /// </summary> + /// <value>The authorization details.</value> + /// <remarks> + /// Because this is a sample, we simply store the authorization information in memory with the user session. + /// A real web app should store at least the access and refresh tokens in this object in a database associated with the user. + /// </remarks> + private static IAuthorizationState Authorization { + get { return (AuthorizationState)HttpContext.Current.Session["Authorization"]; } + set { HttpContext.Current.Session["Authorization"] = value; } + } + + /// <summary> + /// The OAuth 2.0 client object to use to obtain authorization and authorize outgoing HTTP requests. + /// </summary> + private static readonly WebServerClient Client; + + /// <summary> + /// Initializes the <see cref="SampleWcf2"/> class. + /// </summary> + static SampleWcf2() { + Client = new WebServerClient(AuthServerDescription, "sampleconsumer", "samplesecret"); + } + + protected void Page_Load(object sender, EventArgs e) { + if (!IsPostBack) { + // Check to see if we're receiving a end user authorization response. + var authorization = Client.ProcessUserAuthorization(); + if (authorization != null) { + // We are receiving an authorization response. Store it and associate it with this user. + Authorization = authorization; + } + } + } + + 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(); + + Client.RequestUserAuthorization(scopes).Send(); + } + + 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 T CallService<T>(Func<DataApiClient, T> predicate) { + if (Authorization == null) { + throw new InvalidOperationException("No access token!"); + } + + var wcfClient = new DataApiClient(); + + // Refresh the access token if it expires and if its lifetime is too short to be of use. + if (Authorization.AccessTokenExpirationUtc.HasValue) { + Client.RefreshToken(Authorization, TimeSpan.FromMinutes(1)); + } + + var httpRequest = (HttpWebRequest)WebRequest.Create(wcfClient.Endpoint.Address.Uri); + Client.AuthorizeRequest(httpRequest, Authorization.AccessToken); + + var httpDetails = new HttpRequestMessageProperty(); + httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization]; + using (var scope = new OperationContextScope(wcfClient.InnerChannel)) { + OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpDetails; + return predicate(wcfClient); + } + } + } +}
\ 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 2d8d817..0241480 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,11 +51,16 @@ <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"/> <!-- Yammer sign-up: https://www.yammer.com/client_applications/new --> <add key="yammerConsumerKey" value=""/> <add key="yammerConsumerSecret" value=""/> + <!-- Facebook sign-up: http://developers.facebook.com/setup/ --> + <add key="facebookAppID" value="367207604173"/> + <add key="facebookAppSecret" value="1df77e64055c4d7d3583cefdf2bc62d7"/> </appSettings> <connectionStrings/> |