【问题标题】:ASP.Net: Mixed authentication Azure AD / FormsASP.Net:混合身份验证 Azure AD / Forms
【发布时间】:2021-04-16 03:39:12
【问题描述】:

我有一个使用 Forms 身份验证的旧版 Asp.Net/MVC/Razor WebApp。

现在,由于一些用户拥有 Azure AD 帐户,我添加了一个特殊的 AD 登录按钮以及常用代码以使其正常工作

app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {...})

使用按钮登录后,我在 URL 中输入了以下内容:

https://localhost:44361/Account/Index?ReturnUrl=%2fAccount%2fSignIn

因此在我的 Web.config 中我注释掉了:

<!--<authentication mode="Forms">
  <forms loginUrl="~/Account/Index" timeout="2880" cookieless="UseDeviceProfile" />
</authentication>-->

在这个阶段Azure AD 身份验证工作正常!但是这样做,我破坏了原来的 Forms 身份验证:-(

只是打电话

 FormsAuthentication.SetAuthCookie(email, false);

还不够:只要我调用控制器,我仍然会重定向到 Azure AD 登录页面

[System.Web.Mvc.Authorize]

另外我收到错误消息是因为

 @Html.AntiForgeryToken()

类型声明 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' 或者 'http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider' 提供的 ClaimsIdentity 上不存在。启用防伪 基于声明的身份验证的令牌支持,请验证 已配置的声明提供程序在 它生成的 ClaimsIdentity 实例。如果配置的声明 提供者改为使用不同的声明类型作为唯一标识符, 可以通过设置静态属性来配置 AntiForgeryConfig.UniqueClaimTypeIdentifier。

谁能告诉我如何结合这两种身份验证方法? 谢谢!

【问题讨论】:

标签: asp.net-mvc authentication azure-active-directory


【解决方案1】:

这是启动的答案:

    public void ConfigureAuth(IAppBuilder app)
    {
        PublicClientId = "self";

        app.UseCookieAuthentication(new CookieAuthenticationOptions
                                    {
                                            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                                            LoginPath = new PathString("/Account/Index/"),
                                            CookieSecure = CookieSecureOption.Always
                                    });

        app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
                                 {
                                         TokenEndpointPath = new PathString("/Token"),
                                         Provider = new ApplicationOAuthProvider(new StatelessRepository(new DataAccessHelper()), PublicClientId),
                                         RefreshTokenProvider = new AuthenticationTokenProvider
                                                                {
                                                                        OnCreate = CreateRefreshToken,
                                                                        OnReceive = RecieveRefreshToken
                                                                },
                                         AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                                         AccessTokenExpireTimeSpan = TimeSpan.FromHours(1),
                                         AllowInsecureHttp = true
                                 });

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                        ClientId = clientId,
                        Authority = authority,
                        RedirectUri = redirectUri,
                        PostLogoutRedirectUri = redirectUri,
                        Scope = OpenIdConnectScope.OpenIdProfile,
                        ResponseType = OpenIdConnectResponseType.CodeIdToken,
                        TokenValidationParameters = new TokenValidationParameters
                                                    {
                                                            ValidateIssuer = true,
                                                            ValidIssuer = $"https://login.microsoftonline.com/{tenant}/v2.0",
                                                            RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
                                                            NameClaimType = "name",
                                                    },
                        Notifications = new OpenIdConnectAuthenticationNotifications
                                        {
                                                AuthenticationFailed = OnAuthenticationFailed,
                                                SecurityTokenValidated = OnAuthenticationSuccessded
                                        }
                }
        );
    }

在 Web.config 中

<system.web>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.8" />
<httpRuntime targetFramework="4.8" />
</system.web>
      <system.webServer>
        <modules>
          <remove name="FormsAuthentication" />
        </modules>
      </system.webServer>

最后在控制器中,验证用户凭据后:

List<Claim> claims = new List<Claim>
                             {
                                     new Claim(ClaimTypes.Name, partnerUser.Email),
                                     new Claim(ClaimTypes.Email, partnerUser.Email),
                                     new Claim(ClaimTypes.NameIdentifier, partnerUser.Email)
                             };
        ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims,
                DefaultAuthenticationTypes.ApplicationCookie);

        Request.GetOwinContext().Authentication.SignIn(claimsIdentity);

加上一个SignOut方法:

    public void SignOut()
    {
        IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;

        foreach (ClaimsIdentity claimsIdentity in authenticationManager.User.Identities)
        {
            switch (claimsIdentity.AuthenticationType)
            {
                case DefaultAuthenticationTypes.ApplicationCookie:
                    authenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
                    break;

                case CookieAuthenticationDefaults.AuthenticationType:
                    authenticationManager.SignOut(
                            OpenIdConnectAuthenticationDefaults.AuthenticationType,
                            CookieAuthenticationDefaults.AuthenticationType);
                    break;
            }
        }

        Session.Abandon();
        Session.RemoveAll();
    }

最后,这里是 Global.asax 的内容:

    protected void Application_Start()
    {
        AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
        ...           
    }

【讨论】:

    猜你喜欢
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 2020-07-27
    相关资源
    最近更新 更多