diff --git a/src/Gemstone.Web/APIController/ModelController.cs b/src/Gemstone.Web/APIController/ModelController.cs
index c1130a52..c4f2311c 100644
--- a/src/Gemstone.Web/APIController/ModelController.cs
+++ b/src/Gemstone.Web/APIController/ModelController.cs
@@ -23,7 +23,6 @@
// ReSharper disable StaticMemberInGenericType
using System;
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Gemstone.Data;
diff --git a/src/Gemstone.Web/Security/IAuthenticationWebBuilder.cs b/src/Gemstone.Web/Security/IAuthenticationWebBuilder.cs
index 1f52340c..9678072f 100644
--- a/src/Gemstone.Web/Security/IAuthenticationWebBuilder.cs
+++ b/src/Gemstone.Web/Security/IAuthenticationWebBuilder.cs
@@ -24,6 +24,7 @@
using System;
using System.IO;
using System.Net;
+using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Gemstone.Security.AuthenticationProviders;
@@ -171,7 +172,16 @@ private static async Task HandleLogoutRequestAsync(HttpContext httpContext)
// If the sign out procedure did not trigger any errors or redirects,
// this asks the cookie authentication scheme to redirect to the login page
if (IsSuccess(httpContext.Response.StatusCode) && !IsAjaxRequest(httpContext.Request))
- await httpContext.ChallengeAsync(new AuthenticationProperties() { RedirectUri = "/" });
+ {
+ string redirectUri = httpContext.Request.PathBase.HasValue
+ ? $"{httpContext.Request.PathBase}/"
+ : "/";
+
+ await httpContext.ChallengeAsync(new AuthenticationProperties()
+ {
+ RedirectUri = redirectUri
+ });
+ }
}
private static async Task HandleAccessDeniedAsync(HttpContext httpContext)
@@ -256,6 +266,12 @@ public static AuthenticationBuilder ConfigureOAuthProvider(this AuthenticationBu
foreach (string scope in providerOptions.Scopes.Split(' ', StringSplitOptions.RemoveEmptyEntries))
config.Scope.Add(scope);
+
+ config.Events.OnTokenValidated = context =>
+ {
+ AddProviderIdentityClaim(context.Principal, OAuthAuthenticationProviderExtensions.DefaultIdentity);
+ return Task.CompletedTask;
+ };
});
}
@@ -318,7 +334,30 @@ private static AuthenticationBuilder ConfigureGemstoneWebDefaults(this IServiceC
return services
.AddWindowsAuthenticationProvider()
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
- .AddNegotiate("windows", _ => { })
- .AddCookie();
+ .AddNegotiate("windows", options =>
+ {
+ if (options.Events is not null)
+ {
+ options.Events.OnAuthenticated = context =>
+ {
+ AddProviderIdentityClaim(context.Principal, WindowsAuthenticationProviderExtensions.DefaultIdentity);
+ return Task.CompletedTask;
+ };
+ }
+ }).AddCookie();
+ }
+
+ ///
+ /// Adds a claim to the principal indicating the identity of the provider that authenticated the user, if it does not already exist.
+ ///
+ /// The claims principal
+ /// The identity of the authentication provider
+ private static void AddProviderIdentityClaim(ClaimsPrincipal? principal, string providerIdentity)
+ {
+ if (principal?.Identity is not ClaimsIdentity identity)
+ return;
+
+ if (!identity.HasClaim("Gemstone.ProviderIdentity", providerIdentity))
+ identity.AddClaim(new Claim("Gemstone.ProviderIdentity", providerIdentity));
}
}
diff --git a/src/Gemstone.Web/WebExtensions.cs b/src/Gemstone.Web/WebExtensions.cs
index 16fa28c0..b42df9c7 100644
--- a/src/Gemstone.Web/WebExtensions.cs
+++ b/src/Gemstone.Web/WebExtensions.cs
@@ -33,7 +33,6 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.FileProviders;
-using Microsoft.Extensions.Primitives;
namespace Gemstone.Web
{