From afa4c7b697f6e5e98f99da9879350be95b8bd3a3 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 20 Feb 2015 18:51:44 +0100 Subject: [PATCH] open id connect is working with azure ad --- src/Umbraco.Web.UI/App_Code/OwinStartup.cs | 135 ++++++++++++++++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 18 +++ src/Umbraco.Web.UI/packages.config | 4 + .../Editors/BackOfficeController.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 6 + src/Umbraco.Web/packages.config | 1 + 6 files changed, 153 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI/App_Code/OwinStartup.cs b/src/Umbraco.Web.UI/App_Code/OwinStartup.cs index a11e071aa3..a4eb25b341 100644 --- a/src/Umbraco.Web.UI/App_Code/OwinStartup.cs +++ b/src/Umbraco.Web.UI/App_Code/OwinStartup.cs @@ -1,14 +1,11 @@ using System; -using System.Collections.Generic; -using System.Linq; +using System.Globalization; +using System.Net.Http; +using System.Threading.Tasks; using System.Web; -using System.Web.Security; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.Owin; +using Microsoft.IdentityModel.Clients.ActiveDirectory; using Microsoft.Owin; -using Microsoft.Owin.Security.Cookies; -using Microsoft.Owin.Security.Google; -using Umbraco.Web.Security.Identity; +using Microsoft.Owin.Security.OpenIdConnect; using Owin; using Umbraco.Core; using Umbraco.Core.Security; @@ -26,8 +23,23 @@ namespace Umbraco.Web.UI public class OwinStartup { + public async Task DoStuff() + { + var client = new HttpClient(); + + using (var request = await client.PostAsJsonAsync("", "123")) + { + + } + } + public void Configuration(IAppBuilder app) { + + + + + //Single method to configure the Identity user manager for use with Umbraco app.ConfigureUserManagerForUmbracoBackOffice( ApplicationContext.Current, @@ -63,12 +75,111 @@ namespace Umbraco.Web.UI //app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); - app.UseGoogleAuthentication( - clientId: "1072120697051-07jlhgrd5hodsfe7dgqimdie8qc1omet.apps.googleusercontent.com", - clientSecret: "Ue9swN0lEX9rwxzQz1Y_tFzg"); - + + var authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant); + app.UseOpenIdConnectAuthentication( + new OpenIdConnectAuthenticationOptions + { + ClientId = clientId, + Authority = authority, + PostLogoutRedirectUri = postLoginRedirectUri, + + Notifications = new OpenIdConnectAuthenticationNotifications() + { + // + // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away. + // + AuthorizationCodeReceived = (context) => + { + var code = context.Code; + + var credential = new ClientCredential(clientId, appKey); + var userObjectId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value; + var authContext = new AuthenticationContext(authority, new NaiveSessionCache(userObjectId)); + AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode( + code, + //new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), + new Uri( + HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + + HttpContext.Current.Request.RawUrl.EnsureStartsWith('/').EnsureEndsWith('/')), + credential, + graphResourceId); + + return Task.FromResult(0); + } + + } + + }); + } } + + public class NaiveSessionCache : TokenCache + { + private static readonly object FileLock = new object(); + string UserObjectId = string.Empty; + string CacheId = string.Empty; + public NaiveSessionCache(string userId) + { + UserObjectId = userId; + CacheId = UserObjectId + "_TokenCache"; + + this.AfterAccess = AfterAccessNotification; + this.BeforeAccess = BeforeAccessNotification; + Load(); + } + + public void Load() + { + lock (FileLock) + { + this.Deserialize((byte[])HttpContext.Current.Session[CacheId]); + } + } + + public void Persist() + { + lock (FileLock) + { + // reflect changes in the persistent store + HttpContext.Current.Session[CacheId] = this.Serialize(); + // once the write operation took place, restore the HasStateChanged bit to false + this.HasStateChanged = false; + } + } + + // Empties the persistent store. + public override void Clear() + { + base.Clear(); + System.Web.HttpContext.Current.Session.Remove(CacheId); + } + + public override void DeleteItem(TokenCacheItem item) + { + base.DeleteItem(item); + Persist(); + } + + // Triggered right before ADAL needs to access the cache. + // Reload the cache from the persistent store in case it changed since the last access. + void BeforeAccessNotification(TokenCacheNotificationArgs args) + { + Load(); + } + + // Triggered right after ADAL accessed the cache. + void AfterAccessNotification(TokenCacheNotificationArgs args) + { + // if the access operation resulted in a cache update + if (this.HasStateChanged) + { + Persist(); + } + } + } + } \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index f84cdc7f82..52287c9084 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -158,6 +158,16 @@ ..\packages\Microsoft.AspNet.Identity.Owin.2.1.0\lib\net45\Microsoft.AspNet.Identity.Owin.dll + + ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.14.201151115\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + + ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.14.201151115\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll + + + False + ..\packages\Microsoft.IdentityModel.Protocol.Extensions.1.0.1\lib\net45\Microsoft.IdentityModel.Protocol.Extensions.dll + ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll True @@ -181,6 +191,9 @@ False ..\packages\Microsoft.Owin.Security.OAuth.3.0.0\lib\net45\Microsoft.Owin.Security.OAuth.dll + + ..\packages\Microsoft.Owin.Security.OpenIdConnect.3.0.1\lib\net45\Microsoft.Owin.Security.OpenIdConnect.dll + ..\packages\Microsoft.Bcl.Async.1.0.165\lib\net45\Microsoft.Threading.Tasks.dll @@ -232,6 +245,11 @@ + + + False + ..\packages\System.IdentityModel.Tokens.Jwt.4.0.1\lib\net45\System.IdentityModel.Tokens.Jwt.dll + False diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index f60d068561..d7e4304b96 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -22,6 +22,8 @@ + + @@ -29,6 +31,7 @@ + @@ -36,5 +39,6 @@ + \ No newline at end of file diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 47866de5c9..336e1dbfde 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -687,7 +687,7 @@ namespace Umbraco.Web.Editors //Ensure the forms auth module doesn't do a redirect! context.HttpContext.Response.SuppressFormsAuthenticationRedirect = true; - var properties = new AuthenticationProperties() { RedirectUri = RedirectUri }; + var properties = new AuthenticationProperties() { RedirectUri = RedirectUri.EnsureEndsWith('/') }; if (UserId != null) { properties.Dictionary[XsrfKey] = UserId; diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index d409c220ec..0117715330 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -138,6 +138,12 @@ ..\packages\Microsoft.AspNet.Identity.Owin.2.1.0\lib\net45\Microsoft.AspNet.Identity.Owin.dll + + ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.14.201151115\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + + ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.14.201151115\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll + False ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index 318ccab708..6f8f81ffbc 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -18,6 +18,7 @@ +