2015-09-26 82 views
2

我试图将OpenId Connect集成到长期存在的Webforms应用程序中。我能够迁移应用程序以使用OWIN,并且我正在使用OpenIdConnectAuthenticationMiddleware对我的IdP提供程序进行身份验证。一切都很顺利,直到我需要从IdP获得新身份并设置cookie - 我认为哪一部分没有发生。我Startup.Configure方法OpenId Connect中间件未在WebForms应用程序中设置身份验证Cookie

重要部分:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); 

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
    LoginPath = new PathString("/login.aspx"), 
    CookieManager = new SystemWebCookieManager() //custom cookie manager 
}); 


app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions 
{ 
    Authority = "https://[development_domain]/core", 
    ClientId = "VDWeb", 
    ResponseType = "code id_token token", 
    Scope = "openid profile", 
    UseTokenLifetime = true, 
    SignInAsAuthenticationType = "Cookies", 
    Notifications = new OpenIdConnectAuthenticationNotifications 
    { 
     SecurityTokenValidated = async n => 
     { 
      var userInfo = await EndpointAndTokenHelper.CallUserInfoEndpoint(n.ProtocolMessage.AccessToken); 

      //now store Preferred name : 
      var prefNameClaim = new Claim(
       Thinktecture.IdentityModel.Client.JwtClaimTypes.PreferredUserName, 
       userInfo.Value<string>("preferred_username")); 

      var myIdentity = new ClaimsIdentity(
       n.AuthenticationTicket.Identity.AuthenticationType, 
       Thinktecture.IdentityModel.Client.JwtClaimTypes.PreferredUserName, 
       Thinktecture.IdentityModel.Client.JwtClaimTypes.Role); 

      myIdentity.AddClaim(prefNameClaim); 

      //add unique_user_key claim 
      var subjectClaim = n.AuthenticationTicket.Identity.FindFirst(Thinktecture.IdentityModel.Client.JwtClaimTypes.Subject); 

      myIdentity.AddClaim(new Claim("unique_user_key", subjectClaim.Value)); 
      myIdentity.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); 

      var ticket = new AuthenticationTicket(myIdentity, n.AuthenticationTicket.Properties); 
      var currentUtc = new SystemClock().UtcNow; 
      ticket.Properties.IssuedUtc = currentUtc; 
      ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromHours(12)); 
      n.AuthenticationTicket = ticket;     
     }, 
    } 
}); 

我可以证实AuthentocationTicket填充正确,但身份验证cookie不会设置。我确实知道这个问题https://katanaproject.codeplex.com/workitem/197,并且我已经尝试了针对此问题提供的所有解决方法,但没有任何帮助。有趣的是,当我尝试在SecurityTokenValidated事件 - n.Response.Cookies.Append("Test", "Test");中放置我自己的cookie时,我可以看到cookie已正确设置。

其中一种解决方法建议实施您自己的CookieManager。让我感到好奇的是,当我在这个自定义管理器中将一个断点放入Cookie设置器中时,它并未被击中,即中间件似乎甚至不尝试设置cookie。所以我的主要问题 - 中间件到底会在什么时候尝试设置cookie?是否当我设置我的AuthenticationTicket?

编辑1:添加更多信息。我试图与另一个网络应用程序进行比较,这次是MVC,我配置为使用相同的IdP并按预期工作。两款应用的启动代码都是相同的。当通过SecurityTokenValidated事件调试时,我可以看到MVC应用程序(工作)创建了System.Security.Principal.WindowsPrincipal身份,而webforms应用程序(非工作)创建了System.Security.Principal.GenericIdentity身份。

我也加入了这个小文档片断

app.UseStageMarker(PipelineStage.Authenticate); 
app.Use((context, next) => 
{ 
    var identity = context.Request.User.Identity; 
    return next.Invoke(); 
}); 

只是为了看看有什么身份获取填充这个流水线阶段。对于MVC应用程序(工作),我通过设置AuthenticationTicket来看到我添加的身份,对于webforms应用程序,我仍然可以看到未经身份验证的GenericIdentity。

回答

2

OK,这是令人尴尬的 - 问题是CookieAuthenticationOptions,显然AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie一样AuthenticationType = "Cookies"。一旦稍后设置,它工作正常。

+0

您是否使用了特定的解决方案来实施?我正在尝试做类似的事情,但我很难弄清楚在OpenID Connect上的代码示例是如何开始的。 –

0

你可以使用默认的cookie管理器,看看是否导致cookie被设置?

+0

嗨,试用默认的cookie管理器。 Auth cookie仍然**没有**设置,测试cookie(根据我原来的问题)**是**设置。 –

相关问题