如何在OWIN MVC5应用程序中捕获WS-Federation回调以在本地数据库中自动创建标识?

时间:2016-02-16 03:28:33

标签: vb.net authentication asp.net-mvc-5 owin ws-federation

我目前正在开发一个vb.net MVC5应用程序,并使用WS-Federation对来自ADSF 3.0服务器的所有用户进行身份验证。一切都很好;当用户尝试访问标有AUTHORIZE属性的安全控制器时,用户被重定向到STS登录页面,他们登录并返回。我能够阅读ADFS服务器提供的CLAIMS。

我的问题是,当一个新的经过身份验证的用户在登录后进入存储其他信息时,我需要在我的数据库中创建一个本地条目。我不希望用户手动注册,如果他经过身份验证,则表示我可以信任该用户。

Startup.Auth.vb如下所示:

Partial Public Class Startup
Private Shared realm As String = ConfigurationManager.AppSettings("ida:Wtrealm")
Private Shared adfsMetadata As String = ConfigurationManager.AppSettings("ida:ADFSMetadata")

Public Sub ConfigureAuth(app As IAppBuilder)
     app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
        .AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
        .LoginPath = New PathString("/Home/Login")
    })

    app.UseWsFederationAuthentication(New WsFederationAuthenticationOptions() With {
        .AuthenticationType = "ExternalCookie",
        .Wtrealm = realm,
        .MetadataAddress = adfsMetadata,
        .Wreply = "https://myapp.com/Home/SSOLogin"
    })

   app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType)

End Sub

结束班

在我的Home控制器中,我创建了SSOLogin Action,以便能够执行我需要做的测试此用户的存在并创建它(如果它不存在)

Public Function SSOLogin() As ActionResult
    ' Some code here to check if user exists or not and create it   
End Function

我在我的操作中设置了一个断点,但是它从未被命中,因为中间件在它到达action方法之前处理并检测回发并且将Redirect 302重定向到最初请求的安全页面。

问题

有没有什么方法可以在WSFederation中间件中捕获回调,或者可以在global.asax中添加一个事件来仅在身份验证后自动创建用户,而不是在所有请求上?

谢谢你的时间!

1 个答案:

答案 0 :(得分:2)

在WsFederationAuthenticationHandler验证了入站令牌后,您可以注册接收通知。 WsFederationAuthenticationOptions.Notifications是您可以执行此操作的地方。 在startup.cs中,您要为以下内容设置通知:WsFederationAuthenticationNotifications.SecurityTokenValidated。

Patrice,这里有一些代码可以让你了解如何挂钩通知。此代码通常放在startup.auth.cs中。

var wsFederationOptions = new WsFederationAuthenticationOptions
{
  Notifications = new WsFederationAuthenticationNotifications
  {
      SecurityTokenValidated = (notification) =>
      {
         var identity = notification.AuthenticationTicket.Identity;
         var defaultName = identity.FindFirst  ("<claim-that-identifies-user>");

         // do work here
         return Task.FromResult<object>(null);
      }
   },
   MetadataAddress = wsFedMetadataAddress,
   Wreply = host,
   Wtrealm = clientId
};

app.UseWsFederationAuthentication(wsFederationOptions);