diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | samples/OAuth2ProtectedWebApi/Controllers/UserController.cs | 98 | ||||
-rw-r--r-- | samples/OAuthAuthorizationServer/Controllers/AccountController.cs | 101 | ||||
-rw-r--r-- | samples/OAuthAuthorizationServer/Controllers/OAuthController.cs | 134 | ||||
-rw-r--r-- | samples/OAuthAuthorizationServer/Web.config | 205 | ||||
-rw-r--r-- | samples/OpenIdProviderMvc/Controllers/OpenIdController.cs | 386 | ||||
-rw-r--r-- | samples/OpenIdRelyingPartyMvc/Controllers/UserController.cs | 97 |
7 files changed, 511 insertions, 511 deletions
@@ -2,6 +2,7 @@ DotNetOpenAuth ============== [](https://gitter.im/DotNetOpenAuth/DotNetOpenAuth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + A C# implementation of the OpenID, OAuth protocols Samples available: diff --git a/samples/OAuth2ProtectedWebApi/Controllers/UserController.cs b/samples/OAuth2ProtectedWebApi/Controllers/UserController.cs index 2f9b353..f9b8398 100644 --- a/samples/OAuth2ProtectedWebApi/Controllers/UserController.cs +++ b/samples/OAuth2ProtectedWebApi/Controllers/UserController.cs @@ -8,71 +8,71 @@ using System.Web; using System.Web.Mvc; using System.Web.Security; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OAuth2; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OAuth2; using DotNetOpenAuth.OAuth2.Messages; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.RelyingParty; - using OAuth2ProtectedWebApi.Code; + using DotNetOpenAuth.OpenId; + using DotNetOpenAuth.OpenId.RelyingParty; + using OAuth2ProtectedWebApi.Code; public class UserController : Controller { - [Authorize] - [HttpGet] - [HttpHeader("x-frame-options", "SAMEORIGIN")] // mitigates clickjacking + [Authorize] + [HttpGet] + [HttpHeader("x-frame-options", "SAMEORIGIN")] // mitigates clickjacking public async Task<ActionResult> Authorize() { - var authServer = new AuthorizationServer(new AuthorizationServerHost()); - var authRequest = await authServer.ReadAuthorizationRequestAsync(this.Request); - this.ViewData["scope"] = authRequest.Scope; - this.ViewData["request"] = this.Request.Url; - return View(); - } + var authServer = new AuthorizationServer(new AuthorizationServerHost()); + var authRequest = await authServer.ReadAuthorizationRequestAsync(this.Request); + this.ViewData["scope"] = authRequest.Scope; + this.ViewData["request"] = this.Request.Url; + return View(); + } - [Authorize] - [HttpPost, ValidateAntiForgeryToken] + [Authorize] + [HttpPost, ValidateAntiForgeryToken] public async Task<ActionResult> Respond(string request, bool approval) { - var authServer = new AuthorizationServer(new AuthorizationServerHost()); - var authRequest = await authServer.ReadAuthorizationRequestAsync(new Uri(request)); - IProtocolMessage responseMessage; + var authServer = new AuthorizationServer(new AuthorizationServerHost()); + var authRequest = await authServer.ReadAuthorizationRequestAsync(new Uri(request)); + IProtocolMessage responseMessage; if (approval) { - var grantedResponse = authServer.PrepareApproveAuthorizationRequest( - authRequest, this.User.Identity.Name, authRequest.Scope); - responseMessage = grantedResponse; + var grantedResponse = authServer.PrepareApproveAuthorizationRequest( + authRequest, this.User.Identity.Name, authRequest.Scope); + responseMessage = grantedResponse; } else { - var rejectionResponse = authServer.PrepareRejectAuthorizationRequest(authRequest); - rejectionResponse.Error = Protocol.EndUserAuthorizationRequestErrorCodes.AccessDenied; - responseMessage = rejectionResponse; - } + var rejectionResponse = authServer.PrepareRejectAuthorizationRequest(authRequest); + rejectionResponse.Error = Protocol.EndUserAuthorizationRequestErrorCodes.AccessDenied; + responseMessage = rejectionResponse; + } - var response = await authServer.Channel.PrepareResponseAsync(responseMessage); - Response.ContentType = response.Content.Headers.ContentType.ToString(); - return response.AsActionResult(); - } + var response = await authServer.Channel.PrepareResponseAsync(responseMessage); + Response.ContentType = response.Content.Headers.ContentType.ToString(); + return response.AsActionResult(); + } public async Task<ActionResult> Login(string returnUrl) { - var rp = new OpenIdRelyingParty(null); - Realm officialWebSiteHome = Realm.AutoDetect; - Uri returnTo = new Uri(this.Request.Url, this.Url.Action("Authenticate")); - var request = await rp.CreateRequestAsync(WellKnownProviders.Google, officialWebSiteHome, returnTo); + var rp = new OpenIdRelyingParty(null); + Realm officialWebSiteHome = Realm.AutoDetect; + Uri returnTo = new Uri(this.Request.Url, this.Url.Action("Authenticate")); + var request = await rp.CreateRequestAsync(WellKnownProviders.Google, officialWebSiteHome, returnTo); if (returnUrl != null) { - request.SetUntrustedCallbackArgument("returnUrl", returnUrl); - } + request.SetUntrustedCallbackArgument("returnUrl", returnUrl); + } - var redirectingResponse = await request.GetRedirectingResponseAsync(); - Response.ContentType = redirectingResponse.Content.Headers.ContentType.ToString(); - return redirectingResponse.AsActionResult(); - } + var redirectingResponse = await request.GetRedirectingResponseAsync(); + Response.ContentType = redirectingResponse.Content.Headers.ContentType.ToString(); + return redirectingResponse.AsActionResult(); + } public async Task<ActionResult> Authenticate() { - var rp = new OpenIdRelyingParty(null); - var response = await rp.GetResponseAsync(this.Request); + var rp = new OpenIdRelyingParty(null); + var response = await rp.GetResponseAsync(this.Request); if (response != null) { if (response.Status == AuthenticationStatus.Authenticated) { - FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false); - return this.Redirect(FormsAuthentication.GetRedirectUrl(response.ClaimedIdentifier, false)); - } - } + FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false); + return this.Redirect(FormsAuthentication.GetRedirectUrl(response.ClaimedIdentifier, false)); + } + } - return this.RedirectToAction("Index", "Home"); - } - } + return this.RedirectToAction("Index", "Home"); + } + } }
\ No newline at end of file diff --git a/samples/OAuthAuthorizationServer/Controllers/AccountController.cs b/samples/OAuthAuthorizationServer/Controllers/AccountController.cs index f3aa873..b3d24a2 100644 --- a/samples/OAuthAuthorizationServer/Controllers/AccountController.cs +++ b/samples/OAuthAuthorizationServer/Controllers/AccountController.cs @@ -4,77 +4,76 @@ using System.Threading.Tasks; using System.Web.Mvc; using System.Web.Security; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.RelyingParty; - using OAuthAuthorizationServer.Code; - using OAuthAuthorizationServer.Models; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId; + using DotNetOpenAuth.OpenId.RelyingParty; + using OAuthAuthorizationServer.Code; + using OAuthAuthorizationServer.Models; - [HandleError] + [HandleError] public class AccountController : Controller { - // ************************************** - // URL: /Account/LogOn - // ************************************** + // ************************************** + // URL: /Account/LogOn + // ************************************** public ActionResult LogOn() { - return View(); - } + return View(); + } - [HttpPost] + [HttpPost] public async Task<ActionResult> LogOn(LogOnModel model, string returnUrl) { if (ModelState.IsValid) { - var rp = new OpenIdRelyingParty(); - var request = await rp.CreateRequestAsync(model.UserSuppliedIdentifier, Realm.AutoDetect, new Uri(Request.Url, Url.Action("Authenticate"))); + var rp = new OpenIdRelyingParty(); + var request = await rp.CreateRequestAsync(model.UserSuppliedIdentifier, Realm.AutoDetect, new Uri(Request.Url, Url.Action("Authenticate"))); if (request != null) { if (returnUrl != null) { - request.AddCallbackArguments("returnUrl", returnUrl); - } + request.AddCallbackArguments("returnUrl", returnUrl); + } - var response = await request.GetRedirectingResponseAsync(); - Response.ContentType = response.Content.Headers.ContentType.ToString(); - return response.AsActionResult(); + var response = await request.GetRedirectingResponseAsync(); + Response.ContentType = response.Content.Headers.ContentType.ToString(); + return response.AsActionResult(); } else { - ModelState.AddModelError(string.Empty, "The identifier you supplied is not recognized as a valid OpenID Identifier."); - } - } + ModelState.AddModelError(string.Empty, "The identifier you supplied is not recognized as a valid OpenID Identifier."); + } + } - // If we got this far, something failed, redisplay form - return View(model); - } + // If we got this far, something failed, redisplay form + return View(model); + } public async Task<ActionResult> Authenticate(string returnUrl) { - var rp = new OpenIdRelyingParty(); - var response = await rp.GetResponseAsync(Request); + var rp = new OpenIdRelyingParty(); + var response = await rp.GetResponseAsync(Request); if (response != null) { switch (response.Status) { - case AuthenticationStatus.Authenticated: - // Make sure we have a user account for this guy. - string identifier = response.ClaimedIdentifier; // convert to string so LinqToSQL expression parsing works. + case AuthenticationStatus.Authenticated: + // Make sure we have a user account for this guy. + string identifier = response.ClaimedIdentifier; // convert to string so LinqToSQL expression parsing works. if (MvcApplication.DataContext.Users.FirstOrDefault(u => u.OpenIDClaimedIdentifier == identifier) == null) { MvcApplication.DataContext.Users.InsertOnSubmit(new User { - OpenIDFriendlyIdentifier = response.FriendlyIdentifierForDisplay, - OpenIDClaimedIdentifier = response.ClaimedIdentifier, - }); - } + OpenIDFriendlyIdentifier = response.FriendlyIdentifierForDisplay, + OpenIDClaimedIdentifier = response.ClaimedIdentifier, + }); + } - FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false); - return this.Redirect(returnUrl ?? Url.Action("Index", "Home")); + FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false); + return this.Redirect(returnUrl ?? Url.Action("Index", "Home")); + default: + ModelState.AddModelError(string.Empty, "An error occurred during login."); + break; + } + } - default: - ModelState.AddModelError(string.Empty, "An error occurred during login."); - break; - } - } + return this.View("LogOn"); + } - return this.View("LogOn"); - } - - // ************************************** - // URL: /Account/LogOff - // ************************************** + // ************************************** + // URL: /Account/LogOff + // ************************************** public ActionResult LogOff() { - FormsAuthentication.SignOut(); + FormsAuthentication.SignOut(); - return RedirectToAction("Index", "Home"); - } - } + return RedirectToAction("Index", "Home"); + } + } }
\ No newline at end of file diff --git a/samples/OAuthAuthorizationServer/Controllers/OAuthController.cs b/samples/OAuthAuthorizationServer/Controllers/OAuthController.cs index 81c73ca..3953c62 100644 --- a/samples/OAuthAuthorizationServer/Controllers/OAuthController.cs +++ b/samples/OAuthAuthorizationServer/Controllers/OAuthController.cs @@ -1,97 +1,97 @@ namespace OAuthAuthorizationServer.Controllers {
- using System;
+ using System;
using System.Collections.Generic;
- using System.Linq;
- using System.Net;
+ using System.Linq;
+ using System.Net;
using System.Security.Cryptography;
- using System.Threading.Tasks;
- using System.Web;
- using System.Web.Mvc;
+ using System.Threading.Tasks;
+ using System.Web;
+ using System.Web.Mvc;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth2;
using OAuthAuthorizationServer.Code;
using OAuthAuthorizationServer.Models;
public class OAuthController : Controller {
- private readonly AuthorizationServer authorizationServer = new AuthorizationServer(new OAuth2AuthorizationServer());
+ private readonly AuthorizationServer authorizationServer = new AuthorizationServer(new OAuth2AuthorizationServer());
- /// <summary>
- /// The OAuth 2.0 token endpoint.
- /// </summary>
- /// <returns>The response to the Client.</returns>
+ /// <summary>
+ /// The OAuth 2.0 token endpoint.
+ /// </summary>
+ /// <returns>The response to the Client.</returns>
public async Task<ActionResult> Token() {
- var request = await this.authorizationServer.HandleTokenRequestAsync(this.Request, this.Response.ClientDisconnectedToken);
- Response.ContentType = request.Content.Headers.ContentType.ToString();
- return request.AsActionResult();
- }
+ var request = await this.authorizationServer.HandleTokenRequestAsync(this.Request, this.Response.ClientDisconnectedToken);
+ Response.ContentType = request.Content.Headers.ContentType.ToString();
+ return request.AsActionResult();
+ }
- /// <summary>
- /// Prompts the user to authorize a client to access the user's private data.
- /// </summary>
- /// <returns>The browser HTML response that prompts the user to authorize the client.</returns>
- [Authorize, AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
- [HttpHeader("x-frame-options", "SAMEORIGIN")] // mitigates clickjacking
+ /// <summary>
+ /// Prompts the user to authorize a client to access the user's private data.
+ /// </summary>
+ /// <returns>The browser HTML response that prompts the user to authorize the client.</returns>
+ [Authorize, AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
+ [HttpHeader("x-frame-options", "SAMEORIGIN")] // mitigates clickjacking
public async Task<ActionResult> Authorize() {
- var pendingRequest = await this.authorizationServer.ReadAuthorizationRequestAsync(Request, Response.ClientDisconnectedToken);
+ var pendingRequest = await this.authorizationServer.ReadAuthorizationRequestAsync(Request, Response.ClientDisconnectedToken);
if (pendingRequest == null) {
- throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
- }
+ throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
+ }
- var requestingClient = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
+ var requestingClient = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
- // Consider auto-approving if safe to do so.
+ // Consider auto-approving if safe to do so.
if (((OAuth2AuthorizationServer)this.authorizationServer.AuthorizationServerServices).CanBeAutoApproved(pendingRequest)) {
- var approval = this.authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, HttpContext.User.Identity.Name);
- var response = await this.authorizationServer.Channel.PrepareResponseAsync(approval, Response.ClientDisconnectedToken);
- Response.ContentType = response.Content.Headers.ContentType.ToString();
- return response.AsActionResult();
- }
+ var approval = this.authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, HttpContext.User.Identity.Name);
+ var response = await this.authorizationServer.Channel.PrepareResponseAsync(approval, Response.ClientDisconnectedToken);
+ Response.ContentType = response.Content.Headers.ContentType.ToString();
+ return response.AsActionResult();
+ }
var model = new AccountAuthorizeModel {
- ClientApp = requestingClient.Name,
- Scope = pendingRequest.Scope,
- AuthorizationRequest = pendingRequest,
- };
+ ClientApp = requestingClient.Name,
+ Scope = pendingRequest.Scope,
+ AuthorizationRequest = pendingRequest,
+ };
- return View(model);
- }
+ return View(model);
+ }
- /// <summary>
- /// Processes the user's response as to whether to authorize a Client to access his/her private data.
- /// </summary>
- /// <param name="isApproved">if set to <c>true</c>, the user has authorized the Client; <c>false</c> otherwise.</param>
- /// <returns>HTML response that redirects the browser to the Client.</returns>
- [Authorize, HttpPost, ValidateAntiForgeryToken]
+ /// <summary>
+ /// Processes the user's response as to whether to authorize a Client to access his/her private data.
+ /// </summary>
+ /// <param name="isApproved">if set to <c>true</c>, the user has authorized the Client; <c>false</c> otherwise.</param>
+ /// <returns>HTML response that redirects the browser to the Client.</returns>
+ [Authorize, HttpPost, ValidateAntiForgeryToken]
public async Task<ActionResult> AuthorizeResponse(bool isApproved) {
- var pendingRequest = await this.authorizationServer.ReadAuthorizationRequestAsync(Request, Response.ClientDisconnectedToken);
+ var pendingRequest = await this.authorizationServer.ReadAuthorizationRequestAsync(Request, Response.ClientDisconnectedToken);
if (pendingRequest == null) {
- throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
- }
+ throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
+ }
- IDirectedProtocolMessage response;
+ IDirectedProtocolMessage response;
if (isApproved) {
- // The authorization we file in our database lasts until the user explicitly revokes it.
- // You can cause the authorization to expire by setting the ExpirationDateUTC
- // property in the below created ClientAuthorization.
- var client = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
- client.ClientAuthorizations.Add(
+ // The authorization we file in our database lasts until the user explicitly revokes it.
+ // You can cause the authorization to expire by setting the ExpirationDateUTC
+ // property in the below created ClientAuthorization.
+ var client = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
+ client.ClientAuthorizations.Add(
new ClientAuthorization {
- Scope = OAuthUtilities.JoinScopes(pendingRequest.Scope),
- User = MvcApplication.LoggedInUser,
- CreatedOnUtc = DateTime.UtcNow,
- });
- MvcApplication.DataContext.SubmitChanges(); // submit now so that this new row can be retrieved later in this same HTTP request
+ Scope = OAuthUtilities.JoinScopes(pendingRequest.Scope),
+ User = MvcApplication.LoggedInUser,
+ CreatedOnUtc = DateTime.UtcNow,
+ });
+ MvcApplication.DataContext.SubmitChanges(); // submit now so that this new row can be retrieved later in this same HTTP request
- // In this simple sample, the user either agrees to the entire scope requested by the client or none of it.
- // But in a real app, you could grant a reduced scope of access to the client by passing a scope parameter to this method.
- response = this.authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, User.Identity.Name);
+ // In this simple sample, the user either agrees to the entire scope requested by the client or none of it.
+ // But in a real app, you could grant a reduced scope of access to the client by passing a scope parameter to this method.
+ response = this.authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, User.Identity.Name);
} else {
- response = this.authorizationServer.PrepareRejectAuthorizationRequest(pendingRequest);
- }
+ response = this.authorizationServer.PrepareRejectAuthorizationRequest(pendingRequest);
+ }
- var preparedResponse = await this.authorizationServer.Channel.PrepareResponseAsync(response, Response.ClientDisconnectedToken);
- Response.ContentType = preparedResponse.Content.Headers.ContentType.ToString();
- return preparedResponse.AsActionResult();
- }
- }
+ var preparedResponse = await this.authorizationServer.Channel.PrepareResponseAsync(response, Response.ClientDisconnectedToken);
+ Response.ContentType = preparedResponse.Content.Headers.ContentType.ToString();
+ return preparedResponse.AsActionResult();
+ }
+ }
}
\ No newline at end of file diff --git a/samples/OAuthAuthorizationServer/Web.config b/samples/OAuthAuthorizationServer/Web.config index 08cd69b..ff5baed 100644 --- a/samples/OAuthAuthorizationServer/Web.config +++ b/samples/OAuthAuthorizationServer/Web.config @@ -6,119 +6,120 @@ --> <configuration> - <configSections> - <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false" /> - <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core"> - <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" /> - <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" /> - <sectionGroup name="oauth2" type="DotNetOpenAuth.Configuration.OAuth2SectionGroup, DotNetOpenAuth.OAuth2"> - <section name="authorizationServer" type="DotNetOpenAuth.Configuration.OAuth2AuthorizationServerSection, DotNetOpenAuth.OAuth2.AuthorizationServer" requirePermission="false" allowLocation="true" /> - </sectionGroup> - <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" /> - <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" /> - </sectionGroup> - </configSections> + <configSections> + <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false"/> + <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core"> + <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" /> + <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" /> + <sectionGroup name="oauth2" type="DotNetOpenAuth.Configuration.OAuth2SectionGroup, DotNetOpenAuth.OAuth2"> + <section name="authorizationServer" type="DotNetOpenAuth.Configuration.OAuth2AuthorizationServerSection, DotNetOpenAuth.OAuth2.AuthorizationServer" requirePermission="false" allowLocation="true" /> + </sectionGroup> + <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" /> + <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" /> + </sectionGroup> + </configSections> - <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names), - which is necessary for OpenID urls with unicode characters in the domain/host name. - It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. --> - <uri> - <idn enabled="All" /> - <iriParsing enabled="true" /> - </uri> + <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names), + which is necessary for OpenID urls with unicode characters in the domain/host name. + It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. --> + <uri> + <idn enabled="All"/> + <iriParsing enabled="true"/> + </uri> - <system.net> - <defaultProxy enabled="true" /> - <settings> - <!-- This setting causes .NET to check certificate revocation lists (CRL) - before trusting HTTPS certificates. But this setting tends to not - be allowed in shared hosting environments. --> - <!--<servicePointManager checkCertificateRevocationList="true" />--> - </settings> - </system.net> + <system.net> + <defaultProxy enabled="true" /> + <settings> + <!-- This setting causes .NET to check certificate revocation lists (CRL) + before trusting HTTPS certificates. But this setting tends to not + be allowed in shared hosting environments. --> + <!--<servicePointManager checkCertificateRevocationList="true"/>--> + </settings> + </system.net> - <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized --> - <dotNetOpenAuth> - <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. --> - <reporting enabled="true" /> - <oauth2> - <authorizationServer> - </authorizationServer> - </oauth2> + <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized --> + <dotNetOpenAuth> + <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. --> + <reporting enabled="true" /> + <oauth2> + <authorizationServer> + </authorizationServer> + </oauth2> - <!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. --> - <messaging relaxSslRequirements="true"> - <untrustedWebRequest> - <whitelistHosts> - <!-- since this is a sample, and will often be used with localhost --> - <add name="localhost" /> - </whitelistHosts> - </untrustedWebRequest> - </messaging> - </dotNetOpenAuth> + <!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. --> + <messaging relaxSslRequirements="true"> + <untrustedWebRequest> + <whitelistHosts> + <!-- since this is a sample, and will often be used with localhost --> + <add name="localhost"/> + </whitelistHosts> + </untrustedWebRequest> + </messaging> + </dotNetOpenAuth> - <log4net> - <!-- Setup the root category, add the appenders and set the default level --> - <root> - <level value="INFO" /> - <!--<appender-ref ref="RollingFileAppender" />--> - <appender-ref ref="TracePageAppender" /> - </root> - <!-- Specify the level for some specific categories --> - <logger name="DotNetOpenAuth"> - <level value="ALL" /> - </logger> - </log4net> + <log4net> + <!-- Setup the root category, add the appenders and set the default level --> + <root> + <level value="INFO"/> + <!--<appender-ref ref="RollingFileAppender" />--> + <appender-ref ref="TracePageAppender"/> + </root> + <!-- Specify the level for some specific categories --> + <logger name="DotNetOpenAuth"> + <level value="ALL"/> + </logger> + </log4net> - <connectionStrings> + <connectionStrings> <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database4.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" /> - </connectionStrings> + </connectionStrings> - <appSettings> - <add key="ValidationSettings:UnobtrusiveValidationMode" value="None" /> - </appSettings> + <appSettings> + <add key="ValidationSettings:UnobtrusiveValidationMode" value="None" /> + </appSettings> - <system.web> - <httpRuntime targetFramework="4.5" /> - <compilation debug="true" targetFramework="4.0"> - <assemblies> - <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> - <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> - <add assembly="System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> - </assemblies> - </compilation> + <system.web> + <httpRuntime targetFramework="4.5" /> + <compilation debug="true" targetFramework="4.0"> + <assemblies> + <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> + <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> + <add assembly="System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> + </assemblies> + </compilation> - <authentication mode="Forms"> - <forms loginUrl="~/Account/LogOn" timeout="2880" /> - </authentication> + <authentication mode="Forms"> + <forms loginUrl="~/Account/LogOn" timeout="2880" /> + </authentication> - <pages> - <namespaces> - <add namespace="System.Web.Mvc" /> - <add namespace="System.Web.Mvc.Ajax" /> - <add namespace="System.Web.Mvc.Html" /> - <add namespace="System.Web.Routing" /> - </namespaces> - </pages> - </system.web> + <pages> + <namespaces> + <add namespace="System.Web.Mvc" /> + <add namespace="System.Web.Mvc.Ajax" /> + <add namespace="System.Web.Mvc.Html" /> + <add namespace="System.Web.Routing" /> + </namespaces> + </pages> + </system.web> - <system.webServer> - <validation validateIntegratedModeConfiguration="false" /> - <modules runAllManagedModulesForAllRequests="true" /> - <security> - <authentication> - <anonymousAuthentication enabled="true" /> - </authentication> - </security> - </system.webServer> + <system.webServer> + <validation validateIntegratedModeConfiguration="false"/> + <modules runAllManagedModulesForAllRequests="true"/> + <security> + <authentication> + <anonymousAuthentication enabled="true" /> + </authentication> + </security> + </system.webServer> + + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> + <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> - <runtime> - <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> - <dependentAssembly> - <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> - <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> - </dependentAssembly> - </assemblyBinding> - </runtime> -</configuration>
\ No newline at end of file diff --git a/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs b/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs index 14014db..62c5f7f 100644 --- a/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs +++ b/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs @@ -7,273 +7,273 @@ namespace OpenIdProviderMvc.Controllers { using System.Web; using System.Web.Mvc; using System.Web.Mvc.Ajax; - using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.Behaviors; - using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy; - using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.Provider.Behaviors; - using OpenIdProviderMvc.Code; + using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.Provider; + using DotNetOpenAuth.OpenId.Provider.Behaviors; + using OpenIdProviderMvc.Code; public class OpenIdController : Controller { - internal static OpenIdProvider OpenIdProvider = new OpenIdProvider(); + internal static OpenIdProvider OpenIdProvider = new OpenIdProvider(); - public OpenIdController() + public OpenIdController() : this(null) { - } + } public OpenIdController(IFormsAuthentication formsAuthentication) { - this.FormsAuth = formsAuthentication ?? new FormsAuthenticationService(); - } + this.FormsAuth = formsAuthentication ?? new FormsAuthenticationService(); + } - public IFormsAuthentication FormsAuth { get; private set; } + public IFormsAuthentication FormsAuth { get; private set; } - [ValidateInput(false)] + [ValidateInput(false)] public async Task<ActionResult> Provider() { - IRequest request = await OpenIdProvider.GetRequestAsync(this.Request, this.Response.ClientDisconnectedToken); + IRequest request = await OpenIdProvider.GetRequestAsync(this.Request, this.Response.ClientDisconnectedToken); if (request != null) { - // Some requests are automatically handled by DotNetOpenAuth. If this is one, go ahead and let it go. + // Some requests are automatically handled by DotNetOpenAuth. If this is one, go ahead and let it go. if (request.IsResponseReady) { - var response = await OpenIdProvider.PrepareResponseAsync(request, this.Response.ClientDisconnectedToken); - Response.ContentType = response.Content.Headers.ContentType.ToString(); - return response.AsActionResult(); - } + var response = await OpenIdProvider.PrepareResponseAsync(request, this.Response.ClientDisconnectedToken); + Response.ContentType = response.Content.Headers.ContentType.ToString(); + return response.AsActionResult(); + } - // This is apparently one that the host (the web site itself) has to respond to. - ProviderEndpoint.PendingRequest = (IHostProcessedRequest)request; + // This is apparently one that the host (the web site itself) has to respond to. + ProviderEndpoint.PendingRequest = (IHostProcessedRequest)request; - // If PAPE requires that the user has logged in recently, we may be required to challenge the user to log in. - var papeRequest = ProviderEndpoint.PendingRequest.GetExtension<PolicyRequest>(); + // If PAPE requires that the user has logged in recently, we may be required to challenge the user to log in. + var papeRequest = ProviderEndpoint.PendingRequest.GetExtension<PolicyRequest>(); if (papeRequest != null && papeRequest.MaximumAuthenticationAge.HasValue) { - TimeSpan timeSinceLogin = DateTime.UtcNow - this.FormsAuth.SignedInTimestampUtc.Value; + TimeSpan timeSinceLogin = DateTime.UtcNow - this.FormsAuth.SignedInTimestampUtc.Value; if (timeSinceLogin > papeRequest.MaximumAuthenticationAge.Value) { - // The RP wants the user to have logged in more recently than he has. - // We'll have to redirect the user to a login screen. - return this.RedirectToAction("LogOn", "Account", new { returnUrl = this.Url.Action("ProcessAuthRequest") }); - } - } + // The RP wants the user to have logged in more recently than he has. + // We'll have to redirect the user to a login screen. + return this.RedirectToAction("LogOn", "Account", new { returnUrl = this.Url.Action("ProcessAuthRequest") }); + } + } - return await this.ProcessAuthRequest(); + return await this.ProcessAuthRequest(); } else { - // No OpenID request was recognized. This may be a user that stumbled on the OP Endpoint. - return this.View(); - } - } + // No OpenID request was recognized. This may be a user that stumbled on the OP Endpoint. + return this.View(); + } + } public async Task<ActionResult> ProcessAuthRequest() { if (ProviderEndpoint.PendingRequest == null) { - return this.RedirectToAction("Index", "Home"); - } + return this.RedirectToAction("Index", "Home"); + } - // Try responding immediately if possible. - ActionResult response = await this.AutoRespondIfPossibleAsync(); + // Try responding immediately if possible. + ActionResult response = await this.AutoRespondIfPossibleAsync(); if (response != null) { - return response; - } + return response; + } - // We can't respond immediately with a positive result. But if we still have to respond immediately... + // We can't respond immediately with a positive result. But if we still have to respond immediately... if (ProviderEndpoint.PendingRequest.Immediate) { - // We can't stop to prompt the user -- we must just return a negative response. - return await this.SendAssertion(); - } - - return this.RedirectToAction("AskUser"); - } - - /// <summary> - /// Displays a confirmation page. - /// </summary> - /// <returns>The response for the user agent.</returns> - [Authorize] + // We can't stop to prompt the user -- we must just return a negative response. + return await this.SendAssertion(); + } + + return this.RedirectToAction("AskUser"); + } + + /// <summary> + /// Displays a confirmation page. + /// </summary> + /// <returns>The response for the user agent.</returns> + [Authorize] public async Task<ActionResult> AskUser() { if (ProviderEndpoint.PendingRequest == null) { - // Oops... precious little we can confirm without a pending OpenID request. - return this.RedirectToAction("Index", "Home"); - } + // Oops... precious little we can confirm without a pending OpenID request. + return this.RedirectToAction("Index", "Home"); + } - // The user MAY have just logged in. Try again to respond automatically to the RP if appropriate. - ActionResult response = await this.AutoRespondIfPossibleAsync(); + // The user MAY have just logged in. Try again to respond automatically to the RP if appropriate. + ActionResult response = await this.AutoRespondIfPossibleAsync(); if (response != null) { - return response; - } + return response; + } - if (!ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity && + if (!ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity && !this.UserControlsIdentifier(ProviderEndpoint.PendingAuthenticationRequest)) { - return this.Redirect(this.Url.Action("LogOn", "Account", new { returnUrl = this.Request.Url })); - } + return this.Redirect(this.Url.Action("LogOn", "Account", new { returnUrl = this.Request.Url })); + } - this.ViewData["Realm"] = ProviderEndpoint.PendingRequest.Realm; + this.ViewData["Realm"] = ProviderEndpoint.PendingRequest.Realm; - return this.View(); - } + return this.View(); + } - [HttpPost, Authorize, ValidateAntiForgeryToken] + [HttpPost, Authorize, ValidateAntiForgeryToken] public async Task<ActionResult> AskUserResponse(bool confirmed) { - if (!ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity && + if (!ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity && !this.UserControlsIdentifier(ProviderEndpoint.PendingAuthenticationRequest)) { - // The user shouldn't have gotten this far without controlling the identifier we'd send an assertion for. - return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest); - } + // The user shouldn't have gotten this far without controlling the identifier we'd send an assertion for. + return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest); + } if (ProviderEndpoint.PendingAnonymousRequest != null) { - ProviderEndpoint.PendingAnonymousRequest.IsApproved = confirmed; + ProviderEndpoint.PendingAnonymousRequest.IsApproved = confirmed; } else if (ProviderEndpoint.PendingAuthenticationRequest != null) { - ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = confirmed; + ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = confirmed; } else { - throw new InvalidOperationException("There's no pending authentication request!"); - } + throw new InvalidOperationException("There's no pending authentication request!"); + } - return await this.SendAssertion(); - } + return await this.SendAssertion(); + } - /// <summary> - /// Sends a positive or a negative assertion, based on how the pending request is currently marked. - /// </summary> - /// <returns>An MVC redirect result.</returns> + /// <summary> + /// Sends a positive or a negative assertion, based on how the pending request is currently marked. + /// </summary> + /// <returns>An MVC redirect result.</returns> public async Task<ActionResult> SendAssertion() { - var pendingRequest = ProviderEndpoint.PendingRequest; - var authReq = pendingRequest as IAuthenticationRequest; - var anonReq = pendingRequest as IAnonymousRequest; - ProviderEndpoint.PendingRequest = null; // clear session static so we don't do this again + var pendingRequest = ProviderEndpoint.PendingRequest; + var authReq = pendingRequest as IAuthenticationRequest; + var anonReq = pendingRequest as IAnonymousRequest; + ProviderEndpoint.PendingRequest = null; // clear session static so we don't do this again if (pendingRequest == null) { - throw new InvalidOperationException("There's no pending authentication request!"); - } + throw new InvalidOperationException("There's no pending authentication request!"); + } - // Set safe defaults if somehow the user ended up (perhaps through XSRF) here before electing to send data to the RP. + // Set safe defaults if somehow the user ended up (perhaps through XSRF) here before electing to send data to the RP. if (anonReq != null && !anonReq.IsApproved.HasValue) { - anonReq.IsApproved = false; - } + anonReq.IsApproved = false; + } if (authReq != null && !authReq.IsAuthenticated.HasValue) { - authReq.IsAuthenticated = false; - } + authReq.IsAuthenticated = false; + } if (authReq != null && authReq.IsAuthenticated.Value) { if (authReq.IsDirectedIdentity) { - authReq.LocalIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name); - } + authReq.LocalIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name); + } if (!authReq.IsDelegatedIdentifier) { - authReq.ClaimedIdentifier = authReq.LocalIdentifier; - } - } + authReq.ClaimedIdentifier = authReq.LocalIdentifier; + } + } - // Respond to AX/sreg extension requests only on a positive result. - if ((authReq != null && authReq.IsAuthenticated.Value) || + // Respond to AX/sreg extension requests only on a positive result. + if ((authReq != null && authReq.IsAuthenticated.Value) || (anonReq != null && anonReq.IsApproved.Value)) { - // Look for a Simple Registration request. When the AXFetchAsSregTransform behavior is turned on - // in the web.config file as it is in this sample, AX requests will come in as SReg requests. - var claimsRequest = pendingRequest.GetExtension<ClaimsRequest>(); + // Look for a Simple Registration request. When the AXFetchAsSregTransform behavior is turned on + // in the web.config file as it is in this sample, AX requests will come in as SReg requests. + var claimsRequest = pendingRequest.GetExtension<ClaimsRequest>(); if (claimsRequest != null) { - var claimsResponse = claimsRequest.CreateResponse(); + var claimsResponse = claimsRequest.CreateResponse(); - // This simple respond to a request check may be enhanced to only respond to an individual attribute - // request if the user consents to it explicitly, in which case this response extension creation can take - // place in the confirmation page action rather than here. + // This simple respond to a request check may be enhanced to only respond to an individual attribute + // request if the user consents to it explicitly, in which case this response extension creation can take + // place in the confirmation page action rather than here. if (claimsRequest.Email != DemandLevel.NoRequest) { - claimsResponse.Email = User.Identity.Name + "@dotnetopenauth.net"; - } + claimsResponse.Email = User.Identity.Name + "@dotnetopenauth.net"; + } - pendingRequest.AddResponseExtension(claimsResponse); - } + pendingRequest.AddResponseExtension(claimsResponse); + } - // Look for PAPE requests. - var papeRequest = pendingRequest.GetExtension<PolicyRequest>(); + // Look for PAPE requests. + var papeRequest = pendingRequest.GetExtension<PolicyRequest>(); if (papeRequest != null) { - var papeResponse = new PolicyResponse(); + var papeResponse = new PolicyResponse(); if (papeRequest.MaximumAuthenticationAge.HasValue) { - papeResponse.AuthenticationTimeUtc = this.FormsAuth.SignedInTimestampUtc; - } - - pendingRequest.AddResponseExtension(papeResponse); - } - } - - var response = await OpenIdProvider.PrepareResponseAsync(pendingRequest, this.Response.ClientDisconnectedToken); - Response.ContentType = response.Content.Headers.ContentType.ToString(); - return response.AsActionResult(); - } - - /// <summary> - /// Attempts to formulate an automatic response to the RP if the user's profile allows it. - /// </summary> - /// <returns>The ActionResult for the caller to return, or <c>null</c> if no automatic response can be made.</returns> + papeResponse.AuthenticationTimeUtc = this.FormsAuth.SignedInTimestampUtc; + } + + pendingRequest.AddResponseExtension(papeResponse); + } + } + + var response = await OpenIdProvider.PrepareResponseAsync(pendingRequest, this.Response.ClientDisconnectedToken); + Response.ContentType = response.Content.Headers.ContentType.ToString(); + return response.AsActionResult(); + } + + /// <summary> + /// Attempts to formulate an automatic response to the RP if the user's profile allows it. + /// </summary> + /// <returns>The ActionResult for the caller to return, or <c>null</c> if no automatic response can be made.</returns> private async Task<ActionResult> AutoRespondIfPossibleAsync() { - // If the odds are good we can respond to this one immediately (without prompting the user)... - if (await ProviderEndpoint.PendingRequest.IsReturnUrlDiscoverableAsync(OpenIdProvider.Channel.HostFactories, this.Response.ClientDisconnectedToken) == RelyingPartyDiscoveryResult.Success - && User.Identity.IsAuthenticated + // If the odds are good we can respond to this one immediately (without prompting the user)... + if (await ProviderEndpoint.PendingRequest.IsReturnUrlDiscoverableAsync(OpenIdProvider.Channel.HostFactories, this.Response.ClientDisconnectedToken) == RelyingPartyDiscoveryResult.Success + && User.Identity.IsAuthenticated && this.HasUserAuthorizedAutoLogin(ProviderEndpoint.PendingRequest)) { - // Is this is an identity authentication request? (as opposed to an anonymous request)... + // Is this is an identity authentication request? (as opposed to an anonymous request)... if (ProviderEndpoint.PendingAuthenticationRequest != null) { - // If this is directed identity, or if the claimed identifier being checked is controlled by the current user... - if (ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity + // If this is directed identity, or if the claimed identifier being checked is controlled by the current user... + if (ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity || this.UserControlsIdentifier(ProviderEndpoint.PendingAuthenticationRequest)) { - ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = true; - return await this.SendAssertion(); - } - } + ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = true; + return await this.SendAssertion(); + } + } - // If this is an anonymous request, we can respond to that too. + // If this is an anonymous request, we can respond to that too. if (ProviderEndpoint.PendingAnonymousRequest != null) { - ProviderEndpoint.PendingAnonymousRequest.IsApproved = true; - return await this.SendAssertion(); - } - } - - return null; - } - - /// <summary> - /// Determines whether the currently logged in user has authorized auto login to the requesting relying party. - /// </summary> - /// <param name="request">The incoming request.</param> - /// <returns> - /// <c>true</c> if it is safe to respond affirmatively to this request and all extensions - /// without further user confirmation; otherwise, <c>false</c>. - /// </returns> + ProviderEndpoint.PendingAnonymousRequest.IsApproved = true; + return await this.SendAssertion(); + } + } + + return null; + } + + /// <summary> + /// Determines whether the currently logged in user has authorized auto login to the requesting relying party. + /// </summary> + /// <param name="request">The incoming request.</param> + /// <returns> + /// <c>true</c> if it is safe to respond affirmatively to this request and all extensions + /// without further user confirmation; otherwise, <c>false</c>. + /// </returns> private bool HasUserAuthorizedAutoLogin(IHostProcessedRequest request) { - // TODO: host should implement this method meaningfully, consulting their user database. - // Make sure the user likes the RP + // TODO: host should implement this method meaningfully, consulting their user database. + // Make sure the user likes the RP if (true/*User.UserLikesRP(request.Realm))*/) { - // And make sure the RP is only asking for information about the user that the user has granted before. + // And make sure the RP is only asking for information about the user that the user has granted before. if (true/*User.HasGrantedExtensions(request)*/) { - // For now for the purposes of the sample, we'll disallow auto-logins when an sreg request is present. + // For now for the purposes of the sample, we'll disallow auto-logins when an sreg request is present. if (request.GetExtension<ClaimsRequest>() != null) { - return false; - } - - return true; - } - } - - // If we aren't sure the user likes this site and is willing to disclose the requested info, return false - // so the user has the opportunity to explicity choose whether to share his/her info. - return false; - } - - /// <summary> - /// Checks whether the logged in user controls the OP local identifier in the given authentication request. - /// </summary> - /// <param name="authReq">The authentication request.</param> - /// <returns><c>true</c> if the user controls the identifier; <c>false</c> otherwise.</returns> + return false; + } + + return true; + } + } + + // If we aren't sure the user likes this site and is willing to disclose the requested info, return false + // so the user has the opportunity to explicity choose whether to share his/her info. + return false; + } + + /// <summary> + /// Checks whether the logged in user controls the OP local identifier in the given authentication request. + /// </summary> + /// <param name="authReq">The authentication request.</param> + /// <returns><c>true</c> if the user controls the identifier; <c>false</c> otherwise.</returns> private bool UserControlsIdentifier(IAuthenticationRequest authReq) { if (authReq == null) { - throw new ArgumentNullException("authReq"); - } + throw new ArgumentNullException("authReq"); + } if (User == null || User.Identity == null) { - return false; - } - - Uri userLocalIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name); - - // Assuming the URLs on the web server are not case sensitive (on Windows servers they almost never are), - // and usernames aren't either, compare the identifiers without case sensitivity. - // No reason to do this for the PPID identifiers though, since they *can* be case sensitive and are highly - // unlikely to be typed in by the user anyway. - return string.Equals(authReq.LocalIdentifier.ToString(), userLocalIdentifier.ToString(), StringComparison.OrdinalIgnoreCase) || - authReq.LocalIdentifier == PpidGeneration.PpidIdentifierProvider.GetIdentifier(userLocalIdentifier, authReq.Realm); - } - } -}
\ No newline at end of file + return false; + } + + Uri userLocalIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name); + + // Assuming the URLs on the web server are not case sensitive (on Windows servers they almost never are), + // and usernames aren't either, compare the identifiers without case sensitivity. + // No reason to do this for the PPID identifiers though, since they *can* be case sensitive and are highly + // unlikely to be typed in by the user anyway. + return string.Equals(authReq.LocalIdentifier.ToString(), userLocalIdentifier.ToString(), StringComparison.OrdinalIgnoreCase) || + authReq.LocalIdentifier == PpidGeneration.PpidIdentifierProvider.GetIdentifier(userLocalIdentifier, authReq.Realm); + } + } +} diff --git a/samples/OpenIdRelyingPartyMvc/Controllers/UserController.cs b/samples/OpenIdRelyingPartyMvc/Controllers/UserController.cs index defc762..a92329c 100644 --- a/samples/OpenIdRelyingPartyMvc/Controllers/UserController.cs +++ b/samples/OpenIdRelyingPartyMvc/Controllers/UserController.cs @@ -2,77 +2,76 @@ using System; using System.Collections.Generic; using System.Linq; - using System.Threading.Tasks; + using System.Threading.Tasks; using System.Web; - using System.Web.Mvc; - using System.Web.Security; + using System.Web.Mvc; + using System.Web.Security; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.RelyingParty; public class UserController : Controller { - private static OpenIdRelyingParty openid = new OpenIdRelyingParty(); + private static OpenIdRelyingParty openid = new OpenIdRelyingParty(); public ActionResult Index() { if (!User.Identity.IsAuthenticated) { - Response.Redirect("~/User/Login?ReturnUrl=Index"); - } + Response.Redirect("~/User/Login?ReturnUrl=Index"); + } - return View("Index"); - } + return View("Index"); + } public ActionResult Logout() { - FormsAuthentication.SignOut(); - return Redirect("~/Home"); - } + FormsAuthentication.SignOut(); + return Redirect("~/Home"); + } public ActionResult Login() { - // Stage 1: display login form to user - return View("Login"); - } + // Stage 1: display login form to user + return View("Login"); + } - [ValidateInput(false)] + [ValidateInput(false)] public async Task<ActionResult> Authenticate(string returnUrl) { - var response = await openid.GetResponseAsync(this.Request, this.Response.ClientDisconnectedToken); + var response = await openid.GetResponseAsync(this.Request, this.Response.ClientDisconnectedToken); if (response == null) { - // Stage 2: user submitting Identifier - Identifier id; + // Stage 2: user submitting Identifier + Identifier id; if (Identifier.TryParse(Request.Form["openid_identifier"], out id)) { try { - var request = await openid.CreateRequestAsync(Request.Form["openid_identifier"]); - var redirectingResponse = await request.GetRedirectingResponseAsync(this.Response.ClientDisconnectedToken); - Response.ContentType = redirectingResponse.Content.Headers.ContentType.ToString(); - return redirectingResponse.AsActionResult(); + var request = await openid.CreateRequestAsync(Request.Form["openid_identifier"]); + var redirectingResponse = await request.GetRedirectingResponseAsync(this.Response.ClientDisconnectedToken); + Response.ContentType = redirectingResponse.Content.Headers.ContentType.ToString(); + return redirectingResponse.AsActionResult(); } catch (ProtocolException ex) { - ViewData["Message"] = ex.Message; - return View("Login"); - } + ViewData["Message"] = ex.Message; + return View("Login"); + } } else { - ViewData["Message"] = "Invalid identifier"; - return View("Login"); - } + ViewData["Message"] = "Invalid identifier"; + return View("Login"); + } } else { - // Stage 3: OpenID Provider sending assertion response + // Stage 3: OpenID Provider sending assertion response switch (response.Status) { - case AuthenticationStatus.Authenticated: - Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay; - var cookie = FormsAuthentication.GetAuthCookie(response.ClaimedIdentifier, false); - Response.SetCookie(cookie); + case AuthenticationStatus.Authenticated: + Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay; + var cookie = FormsAuthentication.GetAuthCookie(response.ClaimedIdentifier, false); + Response.SetCookie(cookie); if (!string.IsNullOrEmpty(returnUrl)) { - return Redirect(returnUrl); + return Redirect(returnUrl); } else { - return RedirectToAction("Index", "Home"); - } - case AuthenticationStatus.Canceled: - ViewData["Message"] = "Canceled at provider"; - return View("Login"); - - case AuthenticationStatus.Failed: - ViewData["Message"] = response.Exception.Message; - return View("Login"); - } - } - return new EmptyResult(); - } - } -}
\ No newline at end of file + return RedirectToAction("Index", "Home"); + } + case AuthenticationStatus.Canceled: + ViewData["Message"] = "Canceled at provider"; + return View("Login"); + case AuthenticationStatus.Failed: + ViewData["Message"] = response.Exception.Message; + return View("Login"); + } + } + return new EmptyResult(); + } + } +} |