System.Security.Principal.WindowsIdentity(User.Identity)无法填充Azure AD发送的声明

时间:2016-02-22 13:58:41

标签: azure owin openid-connect claims

我已使用OpenIdConnect进行Azure AD身份验证。

我的申请是多租户的。我使用Azure AD进行应用程序身份验证。

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions { });
        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {   ..other fields..   }

成功登录后,在构建并启动应用程序后,它可以正常工作。 ClaimPrincipal已正确填充Azure AD发送的数据。

当在不同的浏览器中运行相同的应用程序时,它非常难以填充。

请建议。

提前致谢, 拉胡

2 个答案:

答案 0 :(得分:2)

我的应用程序中的问题是因为我在我的应用程序中使用的中间件Owin的行为。

Owin的问题: 在OWIN中,响应头集合是响应cookie的主存储位置。但是,System.Web将响应cookie存储在单独的HttpContext.Response.Cookies集合中,然后在发送响应之前将它们写入Response.Headers集合。如果两个方法都在同一个请求上使用,那么这可能会导致冲突,因为Response.Cookies集合将覆盖通过OWIN响应头设置的任何cookie。

不幸的是,这个问题没有通用的解决方案。来自OWIN的set-cookie头无法通过System.Web的Response.Cookies集合可靠地重新解析和重定向。 OWIN组件也不能直接写入System.Web的Response.Cookies集合,因为这会损害其平台独立性。

解决方法: 重新配置CookieAuthenticationMiddleware以直接写入System.Web的cookie集合

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            // ...
            CookieManager = new SystemWebCookieManager()
        });

SystemWebCookieManager类定义如下:

public class SystemWebCookieManager : ICookieManager
{
    public string GetRequestCookie(IOwinContext context, string key)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
        var cookie = webContext.Request.Cookies[key];
        return cookie == null ? null : cookie.Value;
    }

    public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);

        bool domainHasValue = !string.IsNullOrEmpty(options.Domain);
        bool pathHasValue = !string.IsNullOrEmpty(options.Path);
        bool expiresHasValue = options.Expires.HasValue;

        var cookie = new HttpCookie(key, value);
        if (domainHasValue)
        {
            cookie.Domain = options.Domain;
        }
        if (pathHasValue)
        {
            cookie.Path = options.Path;
        }
        if (expiresHasValue)
        {
            cookie.Expires = options.Expires.Value;
        }
        if (options.Secure)
        {
            cookie.Secure = true;
        }
        if (options.HttpOnly)
        {
            cookie.HttpOnly = true;
        }

        webContext.Response.AppendCookie(cookie);
    }

    public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        AppendResponseCookie(
            context,
            key,
            string.Empty,
            new CookieOptions
            {
                Path = options.Path,
                Domain = options.Domain,
                Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
            });
    }
}

它不再给我任何唱歌问题。

答案 1 :(得分:-1)

仅当您的应用程序使用集成身份验证进行身份验证时,才应使用WindowsIdentity。但是,您在这里使用的是OpenID Connect,因此您只能使用ClaimsPrincipal和ClaimsIdentity。