【问题标题】:How to add OpenID combined with Forms Authentication to MVC如何将 OpenID 结合 Forms Authentication 添加到 MVC
【发布时间】:2020-11-06 06:04:55
【问题描述】:

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

除了已经可用的常规登录页面之外,我还需要合并使用 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);

这里是 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");
        }
    }

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

【问题讨论】:

    标签: c# asp.net-mvc authentication forms-authentication openid-connect


    【解决方案1】:

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

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

    【讨论】:

    • 我通过更改 HttpContext.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType); 进一步了解了这一点到 HttpContext.GetOwinContext().Authentication.Challenge("oidc");这使得挑战工作,然后在来自 IDP 的重定向上正确设置了 cookie
    • 嗨@Naner,我完全按照您的代码进行操作,但我使用的是 Azure AD IDP。我有 的网络配置。所以登录页面的访问也被拒绝。有什么想法吗?
    【解决方案2】:

    我能够在 .NET 4.7 中得到这个,或者至少是等效的。我的用例是大多数订阅者正在升级以通过 Azure AD B2C 登录,但我们有公共 PC,我们希望通过隐藏的 URL 手动声明进行身份验证。

    我正在使用Microsoft.Owin.Security.OpenIDConnect和相关的包,Owin启动是标准的,虽然我会指出这一行:

    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    

    我不得不完全禁用 Forms 身份验证;当在 IIS 中启用匿名身份验证以外的任何其他功能时,我无法使其正常工作。

    解决方案的核心实际上是我在这里找到的一个示例:How to use OWIN forms authentication without aspnet identity

        /* URL validated, add authenticated claim */
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, "PublicPC"),
            new Claim(ClaimTypes.Email, "PublicPC@example.org")
        };
        var id = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationType);
    
        var ctx = HttpContext.Current.GetOwinContext();
        var authenticationManager = ctx.Authentication;
        authenticationManager.SignIn(id);
    

    但至关重要的是,我需要指定 CookieAuthenticationDefaults.AuthenticationType,这是我在 Owin 启动时使用的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      • 1970-01-01
      相关资源
      最近更新 更多