summaryrefslogtreecommitdiffstats
path: root/src/OAuth/OAuthAuthorizationServer/Controllers
diff options
context:
space:
mode:
Diffstat (limited to 'src/OAuth/OAuthAuthorizationServer/Controllers')
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Controllers/AccountController.cs78
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Controllers/HomeController.cs59
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Controllers/OAuthController.cs92
3 files changed, 229 insertions, 0 deletions
diff --git a/src/OAuth/OAuthAuthorizationServer/Controllers/AccountController.cs b/src/OAuth/OAuthAuthorizationServer/Controllers/AccountController.cs
new file mode 100644
index 0000000..d69a3b5
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Controllers/AccountController.cs
@@ -0,0 +1,78 @@
+namespace OAuthAuthorizationServer.Controllers {
+ using System;
+ using System.Linq;
+ using System.Web.Mvc;
+ using System.Web.Security;
+
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ using OAuthAuthorizationServer.Code;
+ using OAuthAuthorizationServer.Models;
+
+ [HandleError]
+ public class AccountController : Controller {
+ // **************************************
+ // URL: /Account/LogOn
+ // **************************************
+ public ActionResult LogOn() {
+ return View();
+ }
+
+ [HttpPost]
+ public ActionResult LogOn(LogOnModel model, string returnUrl) {
+ if (ModelState.IsValid) {
+ var rp = new OpenIdRelyingParty();
+ var request = rp.CreateRequest(model.UserSuppliedIdentifier, Realm.AutoDetect, new Uri(Request.Url, Url.Action("Authenticate")));
+ if (request != null) {
+ if (returnUrl != null) {
+ request.AddCallbackArguments("returnUrl", returnUrl);
+ }
+
+ return request.RedirectingResponse.AsActionResult();
+ } else {
+ 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);
+ }
+
+ public ActionResult Authenticate(string returnUrl) {
+ var rp = new OpenIdRelyingParty();
+ var response = rp.GetResponse();
+ 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.
+ if (MvcApplication.DataContext.Users.FirstOrDefault(u => u.OpenIDClaimedIdentifier == identifier) == null) {
+ MvcApplication.DataContext.Users.InsertOnSubmit(new User {
+ OpenIDFriendlyIdentifier = response.FriendlyIdentifierForDisplay,
+ OpenIDClaimedIdentifier = response.ClaimedIdentifier,
+ });
+ }
+
+ FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);
+ return this.Redirect(returnUrl ?? Url.Action("Index", "Home"));
+ default:
+ ModelState.AddModelError(string.Empty, "An error occurred during login.");
+ break;
+ }
+ }
+
+ return this.View("LogOn");
+ }
+
+ // **************************************
+ // URL: /Account/LogOff
+ // **************************************
+ public ActionResult LogOff() {
+ FormsAuthentication.SignOut();
+
+ return RedirectToAction("Index", "Home");
+ }
+ }
+}
diff --git a/src/OAuth/OAuthAuthorizationServer/Controllers/HomeController.cs b/src/OAuth/OAuthAuthorizationServer/Controllers/HomeController.cs
new file mode 100644
index 0000000..d6dd144
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Controllers/HomeController.cs
@@ -0,0 +1,59 @@
+namespace OAuthAuthorizationServer.Controllers {
+ using System.Configuration;
+ using System.Data.SqlClient;
+ using System.IO;
+ using System.Linq;
+ using System.Web.Mvc;
+ using System.Web.Security;
+ using OAuthAuthorizationServer.Code;
+
+ [HandleError]
+ public class HomeController : Controller {
+ public ActionResult Index() {
+ return View();
+ }
+
+ public ActionResult About() {
+ return View();
+ }
+
+ [HttpPost]
+ public ActionResult CreateDatabase() {
+ string databasePath = Path.Combine(Server.MapPath(Request.ApplicationPath), "App_Data");
+ if (!Directory.Exists(databasePath)) {
+ Directory.CreateDirectory(databasePath);
+ }
+ string connectionString = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString.Replace("|DataDirectory|", databasePath);
+ var dc = new DataClassesDataContext(connectionString);
+ if (dc.DatabaseExists()) {
+ dc.DeleteDatabase();
+ }
+ try {
+ dc.CreateDatabase();
+
+ // Add the necessary row for the sample client.
+ dc.Clients.InsertOnSubmit(new Client {
+ ClientIdentifier = "sampleconsumer",
+ ClientSecret = "samplesecret",
+ Name = "Some sample client",
+ });
+ dc.Clients.InsertOnSubmit(new Client {
+ ClientIdentifier = "sampleImplicitConsumer",
+ Name = "Some sample client used for implicit grants (no secret)",
+ Callback = "http://localhost:59721/",
+ });
+
+ dc.SubmitChanges();
+
+ // Force the user to log out because a new database warrants a new row in the users table, which we create
+ // when the user logs in.
+ FormsAuthentication.SignOut();
+ ViewData["Success"] = true;
+ } catch (SqlException ex) {
+ ViewData["Error"] = string.Join("<br>", ex.Errors.OfType<SqlError>().Select(er => er.Message).ToArray());
+ }
+
+ return this.View();
+ }
+ }
+}
diff --git a/src/OAuth/OAuthAuthorizationServer/Controllers/OAuthController.cs b/src/OAuth/OAuthAuthorizationServer/Controllers/OAuthController.cs
new file mode 100644
index 0000000..4260b48
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Controllers/OAuthController.cs
@@ -0,0 +1,92 @@
+namespace OAuthAuthorizationServer.Controllers {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Net;
+ using System.Security.Cryptography;
+ 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());
+
+ /// <summary>
+ /// The OAuth 2.0 token endpoint.
+ /// </summary>
+ /// <returns>The response to the Client.</returns>
+ public ActionResult Token() {
+ return this.authorizationServer.HandleTokenRequest(this.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
+ public ActionResult Authorize() {
+ var pendingRequest = this.authorizationServer.ReadAuthorizationRequest();
+ if (pendingRequest == null) {
+ throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
+ }
+
+ var requestingClient = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
+
+ // 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);
+ return this.authorizationServer.Channel.PrepareResponse(approval).AsActionResult();
+ }
+
+ var model = new AccountAuthorizeModel {
+ ClientApp = requestingClient.Name,
+ Scope = pendingRequest.Scope,
+ AuthorizationRequest = pendingRequest,
+ };
+
+ 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]
+ public ActionResult AuthorizeResponse(bool isApproved) {
+ var pendingRequest = this.authorizationServer.ReadAuthorizationRequest();
+ if (pendingRequest == null) {
+ throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
+ }
+
+ 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(
+ 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
+
+ // 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);
+ }
+
+ return this.authorizationServer.Channel.PrepareResponse(response).AsActionResult();
+ }
+ }
+}