注销后 Azure AD 登录 Web 应用程序失败

问题描述 投票:0回答:1

我正在开发一个在 .net Framework 4.8 上运行的旧 ASP.net MVC 应用程序。 该 Web 应用程序曾经具有自定义登录名,现在已被 Azure AD 身份验证所取代。

我设法将其设置为可以使用 Azure AD 登录到应用程序。但是,一旦我注销应用程序,我就无法再次登录,直到重新启动调试器。有趣的是,我第一次尝试重新登录时,微软登录页面在失败之前快速连续发送了许多单独的请求。

这是我在startup.cs中的设置:

public void Configuration(IAppBuilder app)
{
    //added for troubleshooting
    IdentityModelEventSource.ShowPII = true;

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    ConfigureAuth(app);
}
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions(){
    CookieName = "blargh",
});

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    ClientId = ConfigurationManager.AppSettings["azure:ClientId"],
    Authority = $"{ConfigurationManager.AppSettings["azure:Instance"]}{ConfigurationManager.AppSettings["azure:TenantId"]}",
    RedirectUri = ConfigurationManager.AppSettings["azure:RedirectUri"],
    PostLogoutRedirectUri = ConfigurationManager.AppSettings["azure:PostLogoutRedirectUri"],
    ClientSecret = ConfigurationManager.AppSettings["azure:ClientSecret"],
    ResponseType = OpenIdConnectResponseType.IdToken,
    Scope = OpenIdConnectScope.OpenIdProfile,
    TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true
    },
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        SecurityTokenValidated = context =>
        {
            using (var LoginService = new LoginService())
            {
                var identity = context.AuthenticationTicket.Identity;

                var emailClaim = identity.FindFirst(ClaimTypes.Email)?.Value;

                //omitted - some DB mapping things

                return Task.CompletedTask;
            }
        }
    },
});

这是我的注销逻辑:

public ActionResult Signout()
        {
            try
            {
                HttpContext.GetOwinContext().Authentication.SignOut(
                    DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.ApplicationCookie);
                Session.Abandon();

                var cookie = new HttpCookie("blargh")
                {
                    Expires = DateTime.Now - TimeSpan.FromDays(1),
                };
                Response.Cookies.Add(cookie);

                var redirectUri = Url.Action("Index", "Rapportierung", null, Request.Url.Scheme);
                var logoutUrl = ConfigurationManager.AppSettings["azure:Instance"]
                    + ConfigurationManager.AppSettings["azure:TenantId"]
                    + "/oauth2/v2.0/logout?post_logout_redirect_uri="
                    + ConfigurationManager.AppSettings["azure:PostLogoutRedirectUri"];

                return Redirect(logoutUrl);

            }
            catch (Exception ex)
            {
                //omitted - Error handling
            }
        }

我尝试过各种小调整,例如在 TokenValidationParameters 中设置 ValidateIssuer = true、手动使 cookie 无效(如“blargh”cookie 中所示 - 仍在代码中)、更改重定向 URL、添加/删除尾随/signin-oidc 和许多其他东西。 我也尝试过清除浏览器中的所有 cookie 数据,但没有帮助。如果我切换到不同的浏览器,行为也保持不变 - 一旦我在任何浏览器中注销,登录错误也会在所有其他浏览器中发生。

任何帮助将不胜感激,我正在抓住救命稻草。 最好的问候

asp.net-mvc authentication azure-active-directory
1个回答
0
投票

我在 ASP.NET Web 应用程序 4.8 中使用以下代码,利用 openid 和配置文件成功注销。

代码:

Startup.Auth.cs:

using System;
using System.Configuration;
using System.Security.Claims;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;

namespace WebApplication58
{
    public partial class Startup
    {
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string aadInstance = EnsureTrailingSlash(ConfigurationManager.AppSettings["ida:AADInstance"]);
        private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
        private static string authority = aadInstance + tenantId + "/v2.0";

        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,
                    Scope = "openid profile",

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        SecurityTokenValidated = (context) =>
                        {
                            string name = context.AuthenticationTicket.Identity.FindFirst("name").Value;
                            context.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Name, name, string.Empty));
                            return System.Threading.Tasks.Task.FromResult(0);
                        }
                    }
                });
        }

        private static string EnsureTrailingSlash(string value)
        {
            if (value == null)
            {
                value = string.Empty;
            }

            if (!value.EndsWith("/", StringComparison.Ordinal))
            {
                return value + "/";
            }

            return value;
        }
    }
}

AccountController.cs:

using System.Web;
using System.Web.Mvc;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;

namespace WebApplication58.Controllers
{
    public class AccountController : Controller
    {
        public void SignIn()
        {
            if (!Request.IsAuthenticated)
            {
                HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" },
                    OpenIdConnectAuthenticationDefaults.AuthenticationType);
            }
        }

        public void SignOut()
        {
            string callbackUrl = Url.Action("SignOutCallback", "Account", routeValues: null, protocol: Request.Url.Scheme);

            HttpContext.GetOwinContext().Authentication.SignOut(
                new AuthenticationProperties { RedirectUri = callbackUrl },
                OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
        }

        public ActionResult SignOutCallback()
        {
            if (Request.IsAuthenticated)
            {
                return RedirectToAction("Index", "Home");
            }

            return View();
        }
    }
}

_Layout.cshtml:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

</head>
<body>
    <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-dark bg-dark">
        <div class="container">
            @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            <button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" title="Toggle navigation" aria-controls="navbarSupportedContent"
                    aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse d-sm-inline-flex justify-content-between">
                <ul class="navbar-nav flex-grow-1">
                    <li>@Html.ActionLink("Home", "Index", "Home", new { area = "" }, new { @class = "nav-link" })</li>
                    <li>@Html.ActionLink("About", "About", "Home", new { area = "" }, new { @class = "nav-link" })</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home", new { area = "" }, new { @class = "nav-link" })</li>
                </ul>
                 @Html.Partial("_LoginPartial")
            </div>
        </div>
    </nav>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

index.cshtml:

<main>
    <section class="row" aria-labelledby="aspnetTitle">
        <h1 id="title">Hello World</h1>
    </section>
</main>

SignOutCallback.cshtml:

@{
    ViewBag.Title = "Sign Out";
}

<main aria-labelledby="title">
    <h2 id="title">@ViewBag.Title.</h2>
    <p class="text-success">You have successfully signed out.</p>
</main>

我在Azure门户中向openidprofile授予了权限,如下所示。

enter image description here

输出:

我运行了上面的项目,它将我重定向到登录页面,我在其中选择了我的帐户,如下所示:

enter image description here

输出出现在我的帐户的浏览器中,我单击Sign Out按钮注销,如下所示:

enter image description here

它重定向我选择我的帐户进行注销,如下所示:

enter image description here

我已成功退出,如下图。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.