summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--samples/OAuth2ProtectedWebApi/Controllers/UserController.cs98
-rw-r--r--samples/OAuthAuthorizationServer/Controllers/AccountController.cs101
-rw-r--r--samples/OAuthAuthorizationServer/Controllers/OAuthController.cs134
-rw-r--r--samples/OAuthAuthorizationServer/Web.config205
-rw-r--r--samples/OpenIdProviderMvc/Controllers/OpenIdController.cs386
-rw-r--r--samples/OpenIdRelyingPartyMvc/Controllers/UserController.cs97
7 files changed, 511 insertions, 511 deletions
diff --git a/README.md b/README.md
index b34f974..510b164 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,7 @@ DotNetOpenAuth
==============
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](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();
+ }
+ }
+}