Reputation: 67
I am using .NET Core 2-3 with EF Identity cookie auth, and I need to be able to log any given user out of all browsing "sessions" they are logged in for.
To do this, I am "invalidating" the cookie with the following authorization filter:
public class CookieIsValidRequirementHandler : AuthorizationHandler<CookieIsValidRequirement>
{
private readonly ILogger _logger;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly IHttpContextAccessor _httpContextAccessor;
public CookieIsValidRequirementHandler(
ILogger<CookieIsValidRequirementHandler> logger,
SignInManager<IdentityUser> signInManager,
IHttpContextAccessor httpContextAccessor
) {
_logger = logger;
_signInManager = signInManager;
_httpContextAccessor = httpContextAccessor;
}
protected override async Task HandleRequirementAsync(
AuthorizationHandlerContext context,
CookieIsValidRequirement requirement)
{
_logger.LogDebug("Checking if cookie is valid...");
Claim userIdClaim = context.User.FindFirst(ClaimTypes.NameIdentifier);
if (userIdClaim == null || string.IsNullOrWhiteSpace(userIdClaim.Value))
{
_logger.LogDebug($"NameIdentifier Claim not found");
context.Succeed(requirement); // This is needed to allow the home page to load
return;
}
else
{
if (requirement.userIdsToLogOut.Contains(userIdClaim.Value))
{
_logger.LogInformation("Cookie is invalid! Logging user out!");
await _signInManager.SignOutAsync();
requirement.userIdsToLogOut.Remove(userIdClaim.Value);
_logger.LogInformation($"CAN I USE THIS??? {_httpContextAccessor.HttpContext}");
}
else
{
_logger.LogDebug("Cookie is valid!");
context.Succeed(requirement);
}
}
}
This is actually working pretty great, except that it redirects the user to:
https://localhost:5001/Identity/Account/Login?ReturnUrl=%2FIdentity%2FAccount%2FAccessDenied%3FReturnUrl%3D%252F
I like that it redirects them to the login page, but notice that the ReturnUrl is to an Access Denied page. I don't want that.
I've tried looking into the black box here: https://github.com/dotnet/aspnetcore
And it looks like the auth model is tightly related to "schemes" that are "configured" using the small handful of options available in the startup class.
Upvotes: 0
Views: 706
Reputation: 19921
You can redirect to any page you want if you pass in a RedirectUri to SignOutAsync:
public async Task Signout()
{
var props = new AuthenticationProperties()
{
RedirectUri = "/home/login"
};
await HttpContext.SignOutAsync("cookie", props);
}
Upvotes: 0
Reputation: 100
I don't know If I am understanding you correctly, you can config the login and access denied path in the startup file in the ConfigureServices method.
Example:
services.AddAuthentication()
// cookies
.AddCookie(options =>{
options.LoginPath = "/Account/login";
options.AccessDeniedPath = "/Account/login";
});
Upvotes: 1