diff options
Diffstat (limited to 'samples/OAuthServiceProvider')
-rw-r--r-- | samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs | 21 | ||||
-rw-r--r-- | samples/OAuthServiceProvider/Code/Global.cs | 37 | ||||
-rw-r--r-- | samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs | 1 | ||||
-rw-r--r-- | samples/OAuthServiceProvider/Login.aspx | 2 | ||||
-rw-r--r-- | samples/OAuthServiceProvider/OAuth.ashx | 22 | ||||
-rw-r--r-- | samples/OAuthServiceProvider/OAuthServiceProvider.csproj | 11 | ||||
-rw-r--r-- | samples/OAuthServiceProvider/Web.config | 3 |
7 files changed, 71 insertions, 26 deletions
diff --git a/samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs b/samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs index 49da45d..7c80275 100644 --- a/samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs +++ b/samples/OAuthServiceProvider/Code/DatabaseTokenManager.cs @@ -9,13 +9,18 @@ namespace OAuthServiceProvider.Code { using System.Collections.Generic; using System.Diagnostics; using System.Linq; + using System.ServiceModel; + using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; public class DatabaseTokenManager : IServiceProviderTokenManager { + internal OperationContext OperationContext { get; set; } + #region IServiceProviderTokenManager public IConsumerDescription GetConsumer(string consumerKey) { + this.ApplyOperationContext(); var consumerRow = Global.DataContext.OAuthConsumers.SingleOrDefault( consumerCandidate => consumerCandidate.ConsumerKey == consumerKey); if (consumerRow == null) { @@ -27,6 +32,7 @@ namespace OAuthServiceProvider.Code { public IServiceProviderRequestToken GetRequestToken(string token) { try { + this.ApplyOperationContext(); return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State != TokenAuthorizationState.AccessToken); } catch (InvalidOperationException ex) { throw new KeyNotFoundException("Unrecognized token", ex); @@ -34,6 +40,7 @@ namespace OAuthServiceProvider.Code { } public IServiceProviderAccessToken GetAccessToken(string token) { + this.ApplyOperationContext(); try { return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State == TokenAuthorizationState.AccessToken); } catch (InvalidOperationException ex) { @@ -54,6 +61,7 @@ namespace OAuthServiceProvider.Code { #region ITokenManager Members public string GetTokenSecret(string token) { + this.ApplyOperationContext(); var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault( tokenCandidate => tokenCandidate.Token == token); if (tokenRow == null) { @@ -64,6 +72,7 @@ namespace OAuthServiceProvider.Code { } public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) { + this.ApplyOperationContext(); RequestScopedTokenMessage scopedRequest = (RequestScopedTokenMessage)request; var consumer = Global.DataContext.OAuthConsumers.Single(consumerRow => consumerRow.ConsumerKey == request.ConsumerKey); string scope = scopedRequest.Scope; @@ -90,6 +99,7 @@ namespace OAuthServiceProvider.Code { /// been authorized, has expired or does not exist. /// </returns> public bool IsRequestTokenAuthorized(string requestToken) { + this.ApplyOperationContext(); var tokenFound = Global.DataContext.OAuthTokens.SingleOrDefault( token => token.Token == requestToken && token.State == TokenAuthorizationState.AuthorizedRequestToken); @@ -97,6 +107,8 @@ namespace OAuthServiceProvider.Code { } public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) { + this.ApplyOperationContext(); + var data = Global.DataContext; var consumerRow = data.OAuthConsumers.Single(consumer => consumer.ConsumerKey == consumerKey); var tokenRow = data.OAuthTokens.Single(token => token.Token == requestToken && token.OAuthConsumer == consumerRow); @@ -115,6 +127,7 @@ namespace OAuthServiceProvider.Code { /// <param name="token">The token to classify.</param> /// <returns>Request or Access token, or invalid if the token is not recognized.</returns> public TokenType GetTokenType(string token) { + this.ApplyOperationContext(); var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(tokenCandidate => tokenCandidate.Token == token); if (tokenRow == null) { return TokenType.InvalidToken; @@ -135,6 +148,7 @@ namespace OAuthServiceProvider.Code { throw new ArgumentNullException("user"); } + this.ApplyOperationContext(); var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault( tokenCandidate => tokenCandidate.Token == requestToken && tokenCandidate.State == TokenAuthorizationState.UnauthorizedRequestToken); @@ -151,6 +165,7 @@ namespace OAuthServiceProvider.Code { throw new ArgumentNullException("requestToken"); } + this.ApplyOperationContext(); var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault( tokenCandidate => tokenCandidate.Token == token); if (tokenRow == null) { @@ -159,5 +174,11 @@ namespace OAuthServiceProvider.Code { return tokenRow.OAuthConsumer; } + + private void ApplyOperationContext() { + if (this.OperationContext != null && OperationContext.Current == null) { + OperationContext.Current = this.OperationContext; + } + } } }
\ No newline at end of file diff --git a/samples/OAuthServiceProvider/Code/Global.cs b/samples/OAuthServiceProvider/Code/Global.cs index 60fed9f..37206ab 100644 --- a/samples/OAuthServiceProvider/Code/Global.cs +++ b/samples/OAuthServiceProvider/Code/Global.cs @@ -10,6 +10,10 @@ /// The web application global events and properties. /// </summary> public class Global : HttpApplication { + private readonly object syncObject = new object(); + + private volatile bool initialized; + /// <summary> /// An application memory cache of recent log messages. /// </summary> @@ -95,17 +99,6 @@ private void Application_Start(object sender, EventArgs e) { log4net.Config.XmlConfigurator.Configure(); Logger.Info("Sample starting..."); - string appPath = HttpContext.Current.Request.ApplicationPath; - if (!appPath.EndsWith("/")) { - appPath += "/"; - } - - // This will break in IIS Integrated Pipeline mode, since applications - // start before the first incoming request context is available. - // TODO: fix this. - Constants.WebRootUrl = new Uri(HttpContext.Current.Request.Url, appPath); - Global.TokenManager = new DatabaseTokenManager(); - Global.NonceStore = new DatabaseNonceStore(); } private void Application_End(object sender, EventArgs e) { @@ -128,8 +121,30 @@ } } + private void Application_BeginRequest(object sender, EventArgs e) { + this.EnsureInitialized(); + } + private void Application_EndRequest(object sender, EventArgs e) { CommitAndCloseDatabaseIfNecessary(); } + + private void EnsureInitialized() { + if (!this.initialized) { + lock (this.syncObject) { + if (!this.initialized) { + string appPath = HttpContext.Current.Request.ApplicationPath; + if (!appPath.EndsWith("/")) { + appPath += "/"; + } + + Constants.WebRootUrl = new Uri(HttpContext.Current.Request.Url, appPath); + Global.TokenManager = new DatabaseTokenManager(); + Global.NonceStore = new DatabaseNonceStore(); + this.initialized = true; + } + } + } + } } }
\ No newline at end of file diff --git a/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs b/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs index cf28c15..2d942b5 100644 --- a/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs +++ b/samples/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs @@ -26,6 +26,7 @@ HttpRequestMessageProperty httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; Uri requestUri = operationContext.RequestContext.RequestMessage.Properties.Via; ServiceProvider sp = Constants.CreateServiceProvider(); + ((DatabaseTokenManager)sp.TokenManager).OperationContext = operationContext; // artificially preserve this across thread changes. return Task.Run( async delegate { try { diff --git a/samples/OAuthServiceProvider/Login.aspx b/samples/OAuthServiceProvider/Login.aspx index 4498ee0..0b84ab9 100644 --- a/samples/OAuthServiceProvider/Login.aspx +++ b/samples/OAuthServiceProvider/Login.aspx @@ -1,4 +1,4 @@ -<%@ Page Title="Login" Language="C#" MasterPageFile="~/MasterPage.master" %> +<%@ Page Title="Login" Language="C#" MasterPageFile="~/MasterPage.master" Async="true" %> <%@ Register Assembly="DotNetOpenAuth.OpenId.RelyingParty.UI" Namespace="DotNetOpenAuth.OpenId.RelyingParty" TagPrefix="rp" %> diff --git a/samples/OAuthServiceProvider/OAuth.ashx b/samples/OAuthServiceProvider/OAuth.ashx index 8a74926..7b3dc75 100644 --- a/samples/OAuthServiceProvider/OAuth.ashx +++ b/samples/OAuthServiceProvider/OAuth.ashx @@ -2,41 +2,45 @@ using System; using System.Linq; +using System.Threading.Tasks; using System.Web; using System.Web.SessionState; +using DotNetOpenAuth.ApplicationBlock; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; using DotNetOpenAuth.Messaging; using OAuthServiceProvider.Code; -public class OAuth : IHttpHandler, IRequiresSessionState { +public class OAuth : HttpAsyncHandlerBase, IRequiresSessionState { ServiceProvider sp; public OAuth() { sp = new ServiceProvider(Constants.SelfDescription, Global.TokenManager, new CustomOAuthMessageFactory(Global.TokenManager)); } - public void ProcessRequest(HttpContext context) { - IProtocolMessage request = sp.ReadRequest(); + public override bool IsReusable { + get { return true; } + } + + protected override async Task ProcessRequestAsync(HttpContext context) { + IProtocolMessage request = await sp.ReadRequestAsync(); RequestScopedTokenMessage requestToken; UserAuthorizationRequest requestAuth; AuthorizedTokenRequest requestAccessToken; if ((requestToken = request as RequestScopedTokenMessage) != null) { var response = sp.PrepareUnauthorizedTokenMessage(requestToken); - sp.Channel.Send(response); + var responseMessage = await sp.Channel.PrepareResponseAsync(response); + await responseMessage.SendAsync(new HttpResponseWrapper(context.Response)); } else if ((requestAuth = request as UserAuthorizationRequest) != null) { Global.PendingOAuthAuthorization = requestAuth; HttpContext.Current.Response.Redirect("~/Members/Authorize.aspx"); } else if ((requestAccessToken = request as AuthorizedTokenRequest) != null) { var response = sp.PrepareAccessTokenMessage(requestAccessToken); - sp.Channel.Send(response); + var responseMessage = await sp.Channel.PrepareResponseAsync(response); + await responseMessage.SendAsync(new HttpResponseWrapper(context.Response)); } else { throw new InvalidOperationException(); } } - - public bool IsReusable { - get { return true; } - } } diff --git a/samples/OAuthServiceProvider/OAuthServiceProvider.csproj b/samples/OAuthServiceProvider/OAuthServiceProvider.csproj index 2be5873..65d5a1f 100644 --- a/samples/OAuthServiceProvider/OAuthServiceProvider.csproj +++ b/samples/OAuthServiceProvider/OAuthServiceProvider.csproj @@ -26,7 +26,7 @@ <RootNamespace>OAuthServiceProvider</RootNamespace> <AssemblyName>OAuthServiceProvider</AssemblyName> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> - <UseIISExpress>false</UseIISExpress> + <UseIISExpress>true</UseIISExpress> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -190,6 +190,10 @@ <Project>{3896A32A-E876-4C23-B9B8-78E17D134CD3}</Project> <Name>DotNetOpenAuth.OpenId</Name> </ProjectReference> + <ProjectReference Include="..\DotNetOpenAuth.ApplicationBlock\DotNetOpenAuth.ApplicationBlock.csproj"> + <Project>{aa78d112-d889-414b-a7d4-467b34c7b663}</Project> + <Name>DotNetOpenAuth.ApplicationBlock</Name> + </ProjectReference> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> @@ -198,12 +202,11 @@ <VisualStudio> <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}"> <WebProjectProperties> - <UseIIS>False</UseIIS> + <UseIIS>True</UseIIS> <AutoAssignPort>False</AutoAssignPort> <DevelopmentServerPort>65169</DevelopmentServerPort> <DevelopmentServerVPath>/</DevelopmentServerVPath> - <IISUrl> - </IISUrl> + <IISUrl>http://localhost:65169/</IISUrl> <NTLMAuthentication>False</NTLMAuthentication> <UseCustomServer>False</UseCustomServer> <CustomServerUrl> diff --git a/samples/OAuthServiceProvider/Web.config b/samples/OAuthServiceProvider/Web.config index 51e9ca9..84aea1e 100644 --- a/samples/OAuthServiceProvider/Web.config +++ b/samples/OAuthServiceProvider/Web.config @@ -58,7 +58,8 @@ --> <compilation debug="true" targetFramework="4.0"> <assemblies> - <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> + <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> + <add assembly="System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </assemblies> </compilation> <authentication mode="Forms"> |