Невозможно получить доступ к утверждениям или атрибутам saml через Kentor.AuthServices.Owin в MVC
Я создаю приложение.net 4.5 MVC, которое подключается к IdP SAML на основе Shibboleth для обеспечения функциональности единого входа. Для этого я использую промежуточное программное обеспечение Kentor.AuthServices.Owin.
Рассматриваемая служба IdP требует использования зашифрованных утверждений, которые не поддерживаются последней сборкой Kentor.AuthServices. Вместо этого мне пришлось использовать Raschmann-форк этого здесь https://github.com/Raschmann/authservices/tree/78EncryptedAssertion (v0.8.1), затем попытался..Raschmann / authservices / tree / Release (v0.10.1).
(Использование..Raschmann/authservices/tree/master (v0.12.1) - или любой другой сборки KentorIT Kentor.AuthServices - приводит к тому, что loginInfo будет иметь значение null в ExternalLoginCallback.)
Использование выше позволяет мне войти / зарегистрироваться на приложение через IdP. Однако при вызове ExternalLoginCallback объекты ExternalClaims или Claims в loginInfo.ExternalIdentity не содержат никаких утверждений.
Я собрал и расшифровал ответ SAML от IdP и подтвердил, что он отправляет информацию (такую как имя, фамилия, DoB и т. Д.) Обратно в мое приложение после входа в систему.
Как я могу получить доступ к данным SAML, которые возвращаются?
ConfigureAuth в Startup.Auth.vb:
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
ExternalLoginCallback в AccountController.vb:
<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 ответ
Трубопровод owin довольно сложный. Для отладки я бы предложил вставить небольшое промежуточное ПО точки останова непосредственно перед UseKentorAuthServicesAuthentication()
вызов.
app.Use(async (context, next) =>
{
await next.Invoke();
});
Извините за использование C#, но я предполагаю, что вы можете найти эквивалентный синтаксис VB.
Запустите приложение и авторизуйтесь. Непосредственно перед тем, как запустить Idp для отправки ответа, поставьте точку останова на закрывающей скобке приведенного выше фрагмента кода. Затем исследуйте содержимое context.Authentication.AuthenticationResponseGrant. Это фактическая форма вывода Kentor.AuthServices. Есть ли претензии там?
Если это не так, то есть ошибка в AuthServices. Пожалуйста, сообщите об этом как о проблеме на трекере GitHub Issue, и я посмотрю.
Если претензии действительно присутствуют на тот момент, но позже утеряны, вы можете стать жертвой монстра печенья Оуэна.