最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

authentication - After ASP.NET Core 8 Identity SignOutAsync, the user doesn't have to provide credentials to external lo

programmeradmin6浏览0评论

When using Blazor's IdentityComponentsEndpointRouteBuilderExtensions.cs logout method:

accountGroup.MapPost("/Logout", async (
                ClaimsPrincipal user,
                SignInManager<ApplicationUser> signInManager,
                [FromForm] string returnUrl) =>
            {
                await signInManager.SignOutAsync();
                return TypedResults.LocalRedirect($"~/{returnUrl}");
            });

It does sign the user out of the application (cookies are destroyed), but when logging back in and selecting the same external provider (in my case MS Entra Id), no password is required.

This means anyone can re-log in using the previous email address and external provider with no password required.

I have tried this with other providers, like GitHub and Google and the same situation applies. You can authenticate via the external provider, but never un-authenticate.

Somehow, somewhere there has to be a callback to the external provider to remove the external app credentials.

When using Blazor's IdentityComponentsEndpointRouteBuilderExtensions.cs logout method:

accountGroup.MapPost("/Logout", async (
                ClaimsPrincipal user,
                SignInManager<ApplicationUser> signInManager,
                [FromForm] string returnUrl) =>
            {
                await signInManager.SignOutAsync();
                return TypedResults.LocalRedirect($"~/{returnUrl}");
            });

It does sign the user out of the application (cookies are destroyed), but when logging back in and selecting the same external provider (in my case MS Entra Id), no password is required.

This means anyone can re-log in using the previous email address and external provider with no password required.

I have tried this with other providers, like GitHub and Google and the same situation applies. You can authenticate via the external provider, but never un-authenticate.

Somehow, somewhere there has to be a callback to the external provider to remove the external app credentials.

Share Improve this question edited Mar 26 at 5:28 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 25 at 16:54 TexasJetterTexasJetter 3192 silver badges4 bronze badges 1
  • Hi TexasJetter, To sign out a user, perform both of the following operations: 1. Redirect the user's user-agent to the Microsoft identity platform's logout URI. and 2. Clear your app's cookies or end the user's session in your application. – Jason Pan Commented Mar 26 at 2:53
Add a comment  | 

1 Answer 1

Reset to default 0

After a long day (and not the first) of searching I finally arrived at a solution. @Jason Pan is correct. During the sign-out process you have to call the Microsoft logout URI. My code ended up something like the following:

accountGroup.MapPost("/Logout", async (
    ClaimsPrincipal user,
    SignInManager<ApplicationUser> signInManager,
    [FromForm] string returnUrl,
    HttpContext httpcontext) =>
{
    // Clear the existing browser cookie
    await signInManager.SignOutAsync();
    //If there isn't a return URL, redirect to the login page
    returnUrl = string.IsNullOrEmpty(returnUrl) ? "/Account/Login" : returnUrl;

    if (user.Claims.Any(c => c.ToString().Contains("Microsoft")))
    {
        //If the user is authenticated with a Microsoft account, redirect to the Microsoft logout page
        var redirectUrl = $@"{httpcontext.Request.Scheme}://{httpcontext.Request.Host}{returnUrl}";
        string url = $@"https://login.microsoftonline/common/oauth2/v2.0/logout?post_logout_redirect_uri={redirectUrl}";
        return TypedResults.Redirect(url);
    }
    //Otherwise, redirect to the return URL
    return TypedResults.LocalRedirect(returnUrl);
});

If you have a single MS account logged in (for that browser) it will sign you out and redirect to the provided post_logout_redirect_uri. If you have multiple MS log ins it will ask which one you want to sign out of. In this case I find it does NOT reliably work (i.e. your still signed in w/Microsoft). But I've always had issues with a browser dealing with multiple MS logins.

I don't know if the order of sign out is important or not. If you want to call the MS log out URI first then you'll have to do the signInManager.SignoutAsync() on the callback URI.

I think there is a way to configure this when setting up the external provider but haven't found the right syntax yet. For now this works for my prototype.

It's also worth noting that EACH external provider will have their own logout URI. Somewhere a long time ago I found one for Github. Why oh why do they make it so hard to find? I guess you can check in but never leave :)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论