无法通过MVC中的Kentor.AuthServices.Owin访问声明或saml属性

时间:2015-05-27 10:10:22

标签: vb.net asp.net-mvc-4 saml-2.0 shibboleth kentor-authservices

我正在构建一个连接到基于Shibboleth的SAML IdP的.net 4.5 MVC应用程序,以提供单点登录功能。为此,我使用Kentor.AuthServices.Owin中间件。

有问题的IdP服务需要使用加密断言,Kentor.AuthServices的最新版本不支持这些断言。相反,我必须在这里https://github.com/Raschmann/authservices/tree/78EncryptedAssertion(v0.8.1)使用它的Raschmann-fork,然后尝试..Raschmann / authservices / tree / Release(v0.10.1)。

(使用..Raschmann / authservices / tree / master(v0.12.1) - 或者确实任何KentorIT Kentor.AuthServices构建 - 导致loginInfo在ExternalLoginCallback中为空。)

使用上述功能,我可以通过IdP登录/注册应用程序。但是,当调用ExternalLoginCallback时,loginInfo.ExternalIdentity中的ExternalClaims或Claims对象不包含任何声明。

我已经从IdP中捕获并解密了SAML响应,并在我登录后确认它正在将信息(例如firstname,lastname,DoB等)发送回我的应用程序。

如何访问正在返回的SAML数据?

Startup.Auth.vb中的ConfigureAuth:

Public Sub ConfigureAuth(app As IAppBuilder)
        ' Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(AddressOf ApplicationDbContext.Create)
        app.CreatePerOwinContext(Of ApplicationUserManager)(AddressOf ApplicationUserManager.Create)
        app.CreatePerOwinContext(Of ApplicationSignInManager)(AddressOf ApplicationSignInManager.Create)

        app.UseCookieAuthentication(New CookieAuthenticationOptions() With {
            .AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            .Provider = New CookieAuthenticationProvider() With {
                .OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(Of ApplicationUserManager, ApplicationUser)(
                    validateInterval:=TimeSpan.FromMinutes(30),
                    regenerateIdentity:=Function(manager, user) user.GenerateUserIdentityAsync(manager))},
            .LoginPath = New PathString("/Account/Login")})



app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie)
            app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5))
            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)

            app.UseKentorAuthServicesAuthentication(New KentorAuthServicesAuthenticationOptions(True))
            AntiForgeryConfig.UniqueClaimTypeIdentifier = Global.System.IdentityModel.Claims.ClaimTypes.NameIdentifier

 End Sub

AccountController.vb中的ExternalLoginCallback:

<AllowAnonymous>
    Public Async Function ExternalLoginCallback(returnUrl As String) As Task(Of ActionResult)

        Dim loginInfo = Await AuthenticationManager.GetExternalLoginInfoAsync()

        If loginInfo Is Nothing Then
            Return RedirectToAction("Login")
        End If

        Dim externalIdentity = Await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)

        ' Sign in the user with this external login provider if the user already has a login
        Dim result = Await SignInManager.ExternalSignInAsync(loginInfo, isPersistent:=False)
        Select Case result
            Case SignInStatus.Success
                Dim user = Await UserManager.FindAsync(loginInfo.Login)
                If user IsNot Nothing Then
                    'user.FirstName = loginInfo.ExternalIdentity.FindFirst(ClaimTypes.Name).Value
                    'user.Email = loginInfo.ExternalIdentity.FindFirst(ClaimTypes.Email).Value
                    Await UserManager.UpdateAsync(user)
                End If
                Return RedirectToLocal(returnUrl)
            Case SignInStatus.LockedOut
                Return View("Lockout")
            Case SignInStatus.RequiresVerification
                Return RedirectToAction("SendCode", New With {
                    .ReturnUrl = returnUrl,
                    .RememberMe = False
                })
            Case Else
                ' If the user does not have an account, then prompt the user to create an account
                ViewBag.ReturnUrl = returnUrl
                ViewBag.LoginProvider = loginInfo.Login.LoginProvider
                Return View("ExternalLoginConfirmation", New ExternalLoginConfirmationViewModel() With {
                    .Email = loginInfo.Email
                })
        End Select
    End Function

1 个答案:

答案 0 :(得分:0)

owin管道是quite complex。为了调试这一点,我建议您在UseKentorAuthServicesAuthentication()调用之前插入一个小的断点中间件。

app.Use(async (context, next) =>
{
  await next.Invoke();
});

很抱歉使用C#,但我认为您可以找到等效的VB语法。

运行应用程序并进行身份验证。在触发Idp发回响应之前,在上面的代码片段的结束括号上放置一个断点。然后调查context的内容.Authentication.AuthenticationResponseGrant。这是Kentor.AuthServices的实际输出。索赔是否存在?

如果他们不是,那么AuthServices中就存在一个错误。请在GitHub问题跟踪器中将其报告为问题,我将会看一下。

如果声明确实存在,但稍后丢失,则您可​​能是Owin Cookie Monster的受害者。