1

我有一个现有的 MVC5 应用程序,我正在从使用 AspNetIdentity 转换为使用 ThinkTecture Identity Server 3 v2。OpenID 提供程序不是我遇到的最大问题,因为它似乎运行良好。安全令牌已经过验证,我正在以一种方法处理 SecurityTokenValidated 通知,以便获取额外的用户信息声明并将系统特定的权限声明添加到声明集中,类似于以下代码:

OWIN 中间件

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Authority = "https://localhost:44300/identity",
    Caption = "My Application",
    ClientId = "implicitclient",
    ClientSecret = Convert.ToBase64String(SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes("secret"))),
    RedirectUri = "http://localhost:8080/",
    ResponseType = "id_token token",
    Scope = "openid profile email roles",
    SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
    UseTokenLifetime = false,
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        SecurityTokenValidated = ClaimsTransformer.GenerateUserIdentityAsync
    }
});

索赔变压器

public static async Task GenerateUserIdentityAsync(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
    var identityUser = new ClaimsIdentity(
        notification.AuthenticationTicket.Identity.Claims,
        notification.AuthenticationTicket.Identity.AuthenticationType,
        ClaimTypes.Name,
        ClaimTypes.Role);

    var userInfoClient = new UserInfoClient(new Uri(notification.Options.Authority + "/connect/userinfo"),
        notification.ProtocolMessage.AccessToken);

    var userInfo = await userInfoClient.GetAsync();
    identityUser.AddClaims(userInfo.Claims.Select(t => new Claim(t.Item1, t.Item2)));

    var userName = identityUser.FindFirst("preferred_username").Value;
    var user = MembershipProxy.GetUser(userName);
    var userId = user.PersonID;
    identityUser.AddClaim(new Claim(ClaimTypes.Name, userId.ToString(), ClaimValueTypes.Integer));

    // Populate additional claims

    notification.AuthenticationTicket = new AuthenticationTicket(identityUser, notification.AuthenticationTicket.Properties);
}

问题是在转换器末端分配给身份验证票证的 ClaimsIdentity 从未填充到 System.Web 管道中。当请求在 OnAuthenticationChallenge 期间到达我的控制器时,我检查 User 属性以找到一个匿名的 WindowsPrincipal,它具有分配给 Identity 属性的类似 WindowsIdentity 实例,就好像 Web 配置的system.web/authentication/@mode属性设置为 None(至少我相信这是那个模式)。

什么可能导致中间件无法为用户设置主体,或者在 System.Web 处理期间用匿名 Windows 身份替换它?我一直无法追踪到这一点。

编辑:无论是否处理 SecurityTokenValidated 通知并增加声明,都会发生这种情况。

编辑 2:原因似乎是在我的 web.config 中使用 ASP.NET State Service 会话状态服务器和 cookie。配置条目是:

<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="30" cookieless="UseCookies" />

这看起来与 Microsoft.Owin.Host.SystemWeb #197中报告的问题有关,其中 cookie 没有从 OWIN 请求上下文持久保存到 System.Web 管道中。建议了各种各样的解决方法,但我希望有人权威地向我指出一个经过适当审查的解决方案来解决这个问题。

4

2 回答 2

0

如果您要捕获提琴手跟踪,您是否看到任何 .AspNet.Cookies。我怀疑cookies没有被写入。您可以使用分布式缓存并取消 cookie。

于 2015-07-02T18:56:18.633 回答
0

我认为您需要包含 cookie 身份验证中间件,因为 .AspNet.Cookies 是由该中间件编写的。这就是您可以集成该中间件的方式

app.UseCookieAuthentication(new CookieAuthenticationOptions());

注意:请确保它应该在 openid 连接中间件之上

有关 CookieAuthenticationOptions 的更多详细信息,请转到此链接https://msdn.microsoft.com/en-us/library/microsoft.owin.security.cookies.cookieauthenticationoptions(v=vs.113).aspx

于 2016-07-25T09:56:50.260 回答