ASP.NET 4.8 应用程序启动时的随机 OWIN/OpenID 行为 - 用户有时会自动重定向到 Azure

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

行为怪异。

我的应用程序允许通过内部帐户(使用 ASP.NET Identity)和 Azure AD 进行身份验证。这个想法是显示登录屏幕并由用户决定采用哪种方式。

但有时,第一个请求会完全随机地自动重定向到 Azure AD 进行身份验证。我想说,当我开始调试应用程序时,有四分之一的情况会发生这种情况。

我向 HomeController 添加了日志,并且我知道,在这些时间内用户会自动重定向,控制器构造函数甚至从未被调用过。

这是我的 Startup.Auth.cs 文件:

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            CookieManager = new SystemWebCookieManager(),
            Provider = new CookieAuthenticationProvider()
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });

        var azureAdTenant = System.Configuration.ConfigurationManager.AppSettings["AzureAD:TenantId"];
        var azureAdClientId = System.Configuration.ConfigurationManager.AppSettings["AzureAD:ClientId"];
        var azureAdRedirectUri = System.Configuration.ConfigurationManager.AppSettings["AzureAD:RedirectUri"];
        var azureAdPostLogoutRedirectUri = System.Configuration.ConfigurationManager.AppSettings["AzureAD:PostLogoutRedirectUri"];
        var azureAdAuthority = string.Format(System.Globalization.CultureInfo.InvariantCulture, System.Configuration.ConfigurationManager.AppSettings["AzureAD:Authority"], azureAdTenant);


        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions("AzureAD")
            {
                ClientId = azureAdClientId,
                Authority = azureAdAuthority,
                RedirectUri = azureAdRedirectUri,
                PostLogoutRedirectUri = azureAdPostLogoutRedirectUri,
                Scope = "openid profile User.Read",
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                TokenValidationParameters = new TokenValidationParameters(),
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    RedirectToIdentityProvider = context =>
                    {
                        // Check if it's the auth request we need to modify
                        if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
                        {
                            // Add the extra scope for Graph
                            context.ProtocolMessage.Scope += " https://graph.microsoft.com/Group.Read.All";
                        }

                        return Task.FromResult(0);
                    },
                    AuthenticationFailed = OnAuthenticationFailed,
                    AuthorizationCodeReceived = async context =>
                    {
                        // MSAL Confidential Client setup
                        var confidentialClient = ConfidentialClientApplicationBuilder.Create(azureAdClientId)
                            .WithClientSecret(System.Configuration.ConfigurationManager.AppSettings["AzureAD:AppSecret"])
                            .WithRedirectUri(azureAdRedirectUri)
                            .WithAuthority(new Uri($"https://login.microsoftonline.com/{azureAdTenant}/"))
                            .Build();

                        // Acquiring token using the authorization code
                        var result = await confidentialClient.AcquireTokenByAuthorizationCode(new[] { "https://graph.microsoft.com/.default" }, context.ProtocolMessage.Code)
                            .ExecuteAsync();

                        // Creating an identity for the user and adding claims
                        var appIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie);

                        appIdentity.AddClaim(new Claim("urn:tokens:access_token", result.AccessToken));
                        appIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.JwtSecurityToken.Subject));
                        if (context.JwtSecurityToken.Claims.Any(c => c.Type == "groups"))
                            appIdentity.AddClaim(new Claim("hasGroups", "true"));

                        var externalIdentity = context.AuthenticationTicket.Identity;
                        externalIdentity.AddClaim(new Claim("urn:tokens:access_token", result.AccessToken));

                        // Sign in the user
                        context.OwinContext.Authentication.SignIn(appIdentity);
                    }
                }
            }
        );
    }

    private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
    {
        return Task.FromResult(0);
    }

    private Task OnAuthenticationSucceeded(AuthorizationCodeReceivedNotification context)
    {
        return Task.FromResult(0);
    }
}
asp.net owin openid .net-4.8
1个回答
0
投票

我还不知道为什么,但这个“AuthenticationMode”参数解决了这个问题:

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions("AzureAD")
    {
        AuthenticationMode = AuthenticationMode.Passive,
    }
);
© www.soinside.com 2019 - 2024. All rights reserved.