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 @@
+