3

我将 WIF 与 WS Federation 一起使用,以便我的 ASP.NET 应用程序可以针对 STS(Thinktecture IdentityServer)进行身份验证。在我的 RP 中,我想根据用户的声明务实地设置 cookie 持久性。

观察 Fiddler 中的流量,我可以看到 WIF FedAuth cookie 是在 STS 令牌发布到 RP 时首次设置的。在设置 cookie 之前,我想拦截一些事件并根据当前声明将 cookie 设置为持久(或不持久)。

我知道我可以在 web.config 中设置 cookie 持久性,但是这种行为需要基于用户的条件。

<wsFederation ... persistentCookiesOnPassiveRedirects="true" />

我的第一种方法是尝试处理各种 SessionSecurityTokenCreated 事件,但这些事件似乎从未被触发。 我是否错误地添加了处理程序?或者有没有更好的方法来做到这一点?

protected void Application_Start()
{
    ...

    FederatedAuthentication.SessionAuthenticationModule.SessionSecurityTokenCreated +=
        new EventHandler<SessionSecurityTokenCreatedEventArgs>(SessionAuthenticationModule_SessionSecurityTokenCreated);

    FederatedAuthentication.WSFederationAuthenticationModule.SessionSecurityTokenCreated +=
        new EventHandler<SessionSecurityTokenCreatedEventArgs>(WSFederationAuthenticationModule_SessionSecurityTokenCreated);

}



//This never seems to fire...
void SessionAuthenticationModule_SessionSecurityTokenCreated(object sender,
        SessionSecurityTokenCreatedEventArgs e)
{
    if (e.SessionToken.ClaimsPrincipal.HasClaim("someClaim", "someValue"))
        e.SessionToken.IsPersistent = true;
    else
        e.SessionToken.IsPersistent = false;
}


//This never seems to fire either...
void WSFederationAuthenticationModule_SessionSecurityTokenCreated(object sender,
        SessionSecurityTokenCreatedEventArgs e)
{
    if (e.SessionToken.ClaimsPrincipal.HasClaim("someClaim", "someValue"))
        e.SessionToken.IsPersistent = true;
    else
        e.SessionToken.IsPersistent = false;            

}

有趣的是:如果我为 SessionAuthenticationModule_SessionSecurityTokenReceived 添加一个处理程序,这个事件似乎会触发。在这里,我可以重新发出 cookie 并设置IsPersistent = true但这直到第一次设置 cookie 后才会被触发,我更愿意在第一次发出 cookie 时执行此操作。

经过一番测试:如果我在 SessionAuthenticationModule_SessionSecurityTokenReceived 中重新发出 cookie,那么 SessionAuthenticationModule_SessionSecurityTokenCreated 将被触发。我只是似乎无法找出为什么当令牌首次发布到 RP 时在初始创建 cookie 时没有触发它。

4

1 回答 1

2

我的问题的根源是:a)我使用的是自定义 WSFederationAuthenticationModule。b) 我没有使用自定义模块的名称来连接 Global.asax 中的事件。

假设我的 web.config 里面有这个:

<system.webServer>

// ...

    <add name="MyCustomWSFederationAuthenticationModule"
     type="MyLib.MyCustomWSFederationAuthenticationModule, Thinktecture.IdentityModel, Version=1.0.0.0, Culture=neutral"
     preCondition="managedHandler" />

    <add name="SessionAuthenticationModule"
     type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
     preCondition="managedHandler"  />


// ...

</system.webServer>

并假设“MyCustomWSFederationAuthenticationModule”是自定义 fed-auth 模块的名称。然后我只需要修复方法处理程序的名称(在应用程序启动中没有任何内容)。

protected void Application_Start()
{
    //Nothing here.
}

//This never seems to fire either...
void MyCustomWSFederationAuthenticationModule_SessionSecurityTokenCreated(object sender,
        SessionSecurityTokenCreatedEventArgs e)
{
    if (e.SessionToken.ClaimsPrincipal.HasClaim("someClaim", "someValue"))
        e.SessionToken.IsPersistent = true;
    else
        e.SessionToken.IsPersistent = false;            
}
于 2012-11-08T21:28:02.977 回答