如何在SessionSecurityTokenCreated时有条件地设置FedAuth cookie SessionToken.IsPersistent

时间:2012-11-08 17:01:25

标签: asp.net session-cookies wif ws-federation

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

观察Fiddler中的流量我可以看到当STS令牌发布到RP时,首先设置WIF FedAuth cookie。在设置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时不会触发此操作。

1 个答案:

答案 0 :(得分: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模块的名称。然后我只需要修复方法处理程序的名称(在app start中没有任何内容)。

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;            
}