SSO с AD FS и OWIN, как создать учетную запись и обрабатывать разрешения

Я настраиваю веб-приложение, которое использует AD FS, для этого я использую OWIN.

Для входа в систему все в порядке. Если я пользователь домена и захожу на сайт, он автоматически подключается.

Но то, что я хочу, это обрабатывать пользователей и роли самостоятельно после входа в систему.

Поэтому я хочу проверить, существует ли пользователь в моей базе данных с этой учетной записью AD (этот процесс будет выполнен до входа в другое приложение)

Я хочу использовать удостоверение от Microsoft для обработки претензий (ролей и разрешений). Но я не понимаю, как поместить свой код для обработки успешного соединения из AD FS (с Ws-Federation), добавить проверку и заполнить нужные роли.

Мой код в ConfigureAuth:

public partial class Startup
{
    private static string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
    private static string adfsMetadata = ConfigurationManager.AppSettings["ida:ADFSMetadata"];
    private NLogLoggingService _loggingService;

    public void ConfigureAuth(IAppBuilder app)
    {
        _loggingService = new NLogLoggingService("Startup");
        _loggingService.Debug("ConfigureAuth");

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {
                Wtrealm = realm,
                MetadataAddress = adfsMetadata,

                //CallbackPath = PathString.FromUriComponent("/Account/TestCallback"),

                // https://msdn.microsoft.com/en-us/library/microsoft.owin.security.authenticationmode(v=vs.113).aspx
                AuthenticationMode = AuthenticationMode.Passive,

                //Notifications = new WsFederationAuthenticationNotifications
                //{

                //}
            });

    }

В Web.config область - это ссылка на мое веб-приложение (https: //ssoadfs.test) и adfsMetadata - это ссылка на metadata.xml из AD FS.

Как можно настроить свою роль и логику входа в систему после подключения AD FS?

Схема та, о чем я думал

РЕДАКТИРОВАТЬ: После некоторых попыток я не могу обработать любой обратный вызов успеха. Я не хочу обрабатывать роли в HomeController ...

Мой последний конфиг аутентификации:

            _loggingService = new NLogLoggingService("Startup");
        _loggingService.Debug("ConfigureAuth");

        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationUser.ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ApplicationCookie);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            Provider = new CookieAuthenticationProvider
            {
                OnResponseSignIn = ctx =>
                {
                    _loggingService.Debug("OnResponseSignIn");
                    ctx.Identity = TransformClaims(ctx, app);
                },
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });

        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {
                Wtrealm = realm,
                MetadataAddress = adfsMetadata,
                Caption = "Active Directory",

                CallbackPath = PathString.FromUriComponent("/Account/TestCallback"),

                Notifications = new WsFederationAuthenticationNotifications
                {
                    SecurityTokenValidated = n =>
                    {
                        new NLogLoggingService("Startup").Debug("SecurityTokenValidated");

                        var incomingClaimsFromAdfs = n.AuthenticationTicket.Identity.Claims.ToList();
                        var incomingClaimsHasNameIdentifier =
                            incomingClaimsFromAdfs.Any(
                                c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier);

                        _loggingService.Debug("SecurityTokenValidated - incomingClaimsHasNameIdentifier: " +
                                              incomingClaimsHasNameIdentifier);
                        if (!incomingClaimsHasNameIdentifier)
                        {
                            var emailClaim =
                                incomingClaimsFromAdfs.First(c => c.Type == System.Security.Claims.ClaimTypes.Name);
                            _loggingService.Debug(emailClaim.Value);
                        }

                        //if (!incomingClaimsHasNameIdentifier)
                        //{
                        //    var emailClaim = incomingClaimsFromAdfs.First(c => c.Type == System.Security.Claims.ClaimTypes.Name);
                        //    incomingClaimsFromAdfs.Add();

                        //    IUser user = await this.UserStore.FindByNameOrEmailAsync(userNameOrEmailAddress);
                        //    if ((Entity<long>)user == (Entity<long>)null)
                        //        LoginResult = new ApplicationUserManager.LoginResult(LoginResultType.InvalidUserNameOrEmailAddress, default(IUser));
                        //    //else if (!loggedInFromExternalSource && new PasswordHasher().VerifyHashedPassword(user.Password, plainPassword) != PasswordVerificationResult.Success)
                        //    //    LoginResult = new UserManager<TTenant, TRole, TUser>.LoginResult(LoginResultType.InvalidPassword, user);
                        //    else
                        //        LoginResult = await this.CreateLoginResultAsync(user, tenant);
                        //}
                        //else
                        //{
                        //    throw new ApplicationException("Get ADFS to provide the NameIdentifier claim!");
                        //}

                        //var normalizedClaims = incomingClaimsFromAdfs.Distinct(new ClaimComparer());
                        //var claimsIdentity = new ClaimsIdentity(normalizedClaims, n.AuthenticationTicket.Identity.AuthenticationType);
                        //n.AuthenticationTicket = new AuthenticationTicket(claimsIdentity, n.AuthenticationTicket.Properties);
                        return Task.FromResult(0);
                    }
                }
            });

В этом коде я попробовал CallbackPath (в моем журнале ничего не появилось), WsFederationAuthenticationNotifications.SecurityTokenValidated (в моем журнале ничего не появилось), CookieAuthenticationProvider.OnResponseSignIn (то же самое ничего не произошло)

В HomeController я могу иметь личность. Имя:

public ActionResult Index()
    {
        if (HttpContext.GetOwinContext().Authentication.User.Identity.IsAuthenticated)
        {
            new NLogLoggingService("Home").Debug("User is authenticated");
        }

        return View();
    }

Я что-то пропустил, чтобы заставить работать уведомления или провайдера в CookieAuthenticationOptions ???

Ответы на вопрос(1)

Ваш ответ на вопрос