diff options
Diffstat (limited to 'samples')
-rw-r--r-- | samples/OAuthConsumer/SampleWcf.aspx | 2 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf.aspx.cs | 8 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf2.aspx | 12 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf2.aspx.cs | 62 | ||||
-rw-r--r-- | samples/OAuthConsumer/SampleWcf2.aspx.designer.cs | 54 | ||||
-rw-r--r-- | samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs | 2 | ||||
-rw-r--r-- | samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs | 53 |
7 files changed, 170 insertions, 23 deletions
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 index e8d672b..797a2fc 100644 --- a/samples/OAuthConsumer/SampleWcf2.aspx +++ b/samples/OAuthConsumer/SampleWcf2.aspx @@ -1,4 +1,4 @@ -<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthConsumer.SampleWcf2" Codebehind="SampleWcf2.aspx.cs" %> +<%@ 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"> @@ -10,4 +10,14 @@ <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 index 09ebd12..fa7a102 100644 --- a/samples/OAuthConsumer/SampleWcf2.aspx.cs +++ b/samples/OAuthConsumer/SampleWcf2.aspx.cs @@ -1,16 +1,27 @@ 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) { if (!IsPostBack) { @@ -18,7 +29,7 @@ var authorization = client.ProcessUserAuthorization(); if (authorization != null) { - Response.Write("Obtained access token: " + authorization.AccessToken); + Authorization = authorization; } } } @@ -27,7 +38,7 @@ 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 client = CreateClient(); string clientState; @@ -36,13 +47,56 @@ 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 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); + WebAppClient.AuthorizeRequest(httpRequest, Authorization); + + 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); + } + } + private static WebAppClient 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 WebAppClient(authServerDescription) - { + var client = new WebAppClient(authServerDescription) { ClientIdentifier = "sampleconsumer", ClientSecret = "samplesecret", TokenManager = TokenManager, diff --git a/samples/OAuthConsumer/SampleWcf2.aspx.designer.cs b/samples/OAuthConsumer/SampleWcf2.aspx.designer.cs index 3046936..f42efff 100644 --- a/samples/OAuthConsumer/SampleWcf2.aspx.designer.cs +++ b/samples/OAuthConsumer/SampleWcf2.aspx.designer.cs @@ -38,5 +38,59 @@ namespace OAuthConsumer { /// 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/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs index ed70a15..75778f5 100644 --- a/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs +++ b/samples/OAuthServiceProvider/Code/OAuth2AuthorizationServer.cs @@ -13,7 +13,7 @@ internal class OAuth2AuthorizationServer : IAuthorizationServer { private static readonly byte[] secret; - private static readonly RSAParameters asymmetricKey; + internal static readonly RSAParameters asymmetricKey; private readonly INonceStore nonceStore = new DatabaseNonceStore(); diff --git a/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs b/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs index b12e85a..a48288a 100644 --- a/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs +++ b/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs @@ -9,6 +9,8 @@ using System.ServiceModel.Security; using DotNetOpenAuth; using DotNetOpenAuth.OAuth; + using DotNetOpenAuth.OAuthWrap; + using DotNetOpenAuth.OAuth.ChannelElements; /// <summary> /// A WCF extension to authenticate incoming messages using OAuth. @@ -24,13 +26,10 @@ 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 = VerifyOAuth2(httpDetails, requestUri); + if (principal != null) { var policy = new OAuthPrincipalAuthorizationPolicy(principal); var policies = new List<IAuthorizationPolicy> { policy, @@ -46,14 +45,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 +59,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 |