如何将 OpenID 与 Forms 身份验证结合添加到 MVC

Nan*_*ner 7 c# authentication asp.net-mvc forms-authentication openid-connect

我有一个现有的 MVC 项目,它使用 FormsAuthentication 进行身份验证。

除了现有的常规登录页面之外,我还需要添加使用 OpenID IDP 登录的选项。

我遇到的问题是按需挑战 IDP 并在收到声明后设置身份验证 cookie,我找不到 cookie 不粘的原因。该流程似乎工作正常,我可以在 AuthorizationCodeReceived 回调中看到声明。

这是 Startup.Auth.cs 代码:

var notificationHandlers = new OpenIdConnectAuthenticationNotifications
        {
            AuthorizationCodeReceived = (context) =>
            {
                string username = context.AuthenticationTicket.Identity.FindFirst("preferred_username").Value;
                FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(60), true, "");
                string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                context.Response.Cookies.Append(FormsAuthentication.FormsCookieName, encryptedTicket);

                return Task.FromResult(0);
            },
            RedirectToIdentityProvider = (context) =>
            {
                if (context.OwinContext.Request.Path.Value != "/Account/SignInWithOpenId")
                {
                    context.OwinContext.Response.Redirect("/Account/Login");
                    context.HandleResponse();
                }
                return Task.FromResult(0);
            }
        };

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            AuthenticationType = "oidc",
            SignInAsAuthenticationType = "Cookies",
            Authority = "xxxxxxxxx",
            ClientId = "MyClient",
            ClientSecret = "xxxxxxxx",
            RedirectUri = "http://localhost:52389/",
            PostLogoutRedirectUri = "http://localhost:52389/",
            ResponseType = "code id_token",
            Scope = "openid profile email roles",
            UseTokenLifetime = false,
            TokenValidationParameters = new TokenValidationParameters()
            {
                NameClaimType = "preferred_username",
                RoleClaimType = "role"
            },
            Notifications = notificationHandlers                
        });

        app.SetDefaultSignInAsAuthenticationType("Cookies");

        app.UseCookieAuthentication(new CookieAuthenticationOptions()
        {
            AuthenticationType = "Cookies",
            AuthenticationMode = AuthenticationMode.Passive,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider()
        });

        app.UseStageMarker(PipelineStage.Authenticate);
Run Code Online (Sandbox Code Playgroud)

这是 AccountController SignInWithOpenId 方法:

public ActionResult SignInWithOpenId()
    {
        if (!Request.IsAuthenticated)
        {
            HttpContext.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);

            // If I don't have this line, reponse redirects to the forms authentication login... so maybe something is wrong here?
            return new HttpUnauthorizedResult("IDP");
        }
        else
        {
            return RedirectToAction("Index", "Default");
        }
    }
Run Code Online (Sandbox Code Playgroud)

任何指示将不胜感激。谢谢。

mgt*_*gtb 1

这正是我目前正在尝试做的事情。如果我发现任何有用的东西,我会告诉你。

更新:我最终在 MVC Web 应用程序中禁用了表单身份验证。我正在做一个概念验证,所以这不是一个硬性要求。我知道这不是你真正想要的。我成功使用 IdP 登录并重定向回 Web 应用程序。概念验证结束的地方是需要填充 HttpContext.User 对象。