2

我正在尝试创建一个 ASP.NET MVC 站点,该站点具有受 Windows Azure ACS 保护的特定区域。我希望默认区域不受保护(即允许匿名用户),但只保护子区域。

我通过从我的 Web.config 中的 system.web 部分中删除授权元素来实现这一点。

<authorization>
     <deny users="?" />
</authorization>

然后为所需的 MVC3 区域添加一个受保护的位置。

<location path="MyArea">
    <system.web>
        <authorization>
            <deny users="?" />
        </authorization>
    </system.web>
</location>

但是,我用于访问 IClaimsIdentity 并从中提取属性以进行处理的旧代码曾经存在于我的 Global.asax 的 Session_Start 事件中。既然站点不需要身份验证来访问默认区域,Session_Start 就会发生而无需进行身份验证。

我可以连接什么事件来处理 WIF 的身份验证事件?

我已经使用 SessionAuthenticationModule_SessionSecurityTokenReceived 实现了滑动会话超时,并尝试在 OnPostAuthenticationRequest 事件上添加我的用户分析逻辑,但无济于事。

在第一次连接到以下事件后,我能够获得用户:

FederatedAuthentication.ServiceConfigurationCreated

然后在这个事件中我连接到这个事件:

FederatedAuthentication.WSFederationAuthenticationModule.SignedIn

但是,在此事件中,会话为空,并且再也不会调用 session_start。因此,在重定向到身份提供者时,会话似乎被破坏了。

anon -> Application_start
anon -> Session_start
anon -> 导航到 /MyArea
anon -> 重定向到 ACS -> 重定向到 idP
anon -> 登录
auth -> 重定向到 /MyArea
auth -> FederatedAuthentication.WSFederationAuthenticationModule.SignedIn 发生,但会话一片空白!

更新:我仍然没有找到同时存在会话和身份验证的地方。我正在使用 Unity 按需检测用户。如果有一个事件发生时我会喜欢它,但我的工作仍然有效。

4

2 回答 2

3

根据您想要执行逻辑的时间和方式(登录后、创建会话令牌时、接收后),您有几个选项。该SessionAuthenticationModule_SessionSecurityTokenReceived事件应该可以正常工作,但订阅它可能会很棘手。您可以这样做:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ...

        FederatedAuthentication.FederationConfigurationCreated += (s, e) =>
        {
            FederatedAuthentication.SessionAuthenticationModule.SessionSecurityTokenCreated += SessionAuthenticationModule_SessionSecurityTokenCreated;
            FederatedAuthentication.SessionAuthenticationModule.SessionSecurityTokenReceived += SessionAuthenticationModule_SessionSecurityTokenReceived;
            FederatedAuthentication.WSFederationAuthenticationModule.SessionSecurityTokenCreated += WSFederationAuthenticationModule_SessionSecurityTokenCreated;
            FederatedAuthentication.WSFederationAuthenticationModule.SecurityTokenValidated += WSFederationAuthenticationModule_SecurityTokenValidated;
            FederatedAuthentication.WSFederationAuthenticationModule.SecurityTokenReceived += WSFederationAuthenticationModule_SecurityTokenReceived;
            FederatedAuthentication.WSFederationAuthenticationModule.SignedIn += WSFederationAuthenticationModule_SignedIn;
        };
    }

    void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
    {
        Debugger.Break();
    }

    void SessionAuthenticationModule_SessionSecurityTokenCreated(object sender, SessionSecurityTokenCreatedEventArgs e)
    {
        Debugger.Break();            
    }

    void WSFederationAuthenticationModule_SessionSecurityTokenCreated(object sender, SessionSecurityTokenCreatedEventArgs e)
    {
        Debugger.Break();            
    }

    void WSFederationAuthenticationModule_SecurityTokenValidated(object sender, SecurityTokenValidatedEventArgs e)
    {
        Debugger.Break();            
    }

    void WSFederationAuthenticationModule_SecurityTokenReceived(object sender, SecurityTokenReceivedEventArgs e)
    {
        Debugger.Break();            
    }

    void WSFederationAuthenticationModule_SignedIn(object sender, EventArgs e)
    {
        Debugger.Break();     
    }
}

所有这些代码都在 Global.asax 文件中,并且您希望在 FederationConfigurationCreated 事件引发之后设置事件(此时 SessionAuthenticationModule 和 WSFederationAuthenticationModule 将可用)。我在每个事件处理程序中添加了一个 Debugger.Break。将它们留在那里并调试您的应用程序以查看每个事件何时被触发。这将允许您决定何时何地添加逻辑。

于 2012-12-18T20:00:48.527 回答
0

在要保护的控制器/操作上使用 [Authorize] 属性:

[Authorize]
public ActionResult Index()
{
    return View();
}
于 2012-12-18T19:53:04.377 回答