SSO con AD FS y OWIN cómo crear una cuenta y manejar permisos

Configuro una aplicación web que usa AD FS, para esto uso OWIN.

Para iniciar sesión, todo está bien. Si soy un usuario de un dominio y voy al sitio web, se conecta automáticamente.

Pero lo que quiero tener es manejar usuarios y roles por mí mismo después de iniciar sesión.

Por lo tanto, quiero verificar que exista un usuario en mi base de datos con esta cuenta de AD (este proceso se realizará antes del inicio de sesión en otra aplicación)

Quiero usar Identity from Microsoft para manejar reclamos (roles y permisos). Pero no entiendo cómo poner mi código para manejar la conexión exitosa de AD FS (con Ws-Federation) y agregar verificación y completar los roles correctos.

Mi código en 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
                //{

                //}
            });

    }

En Web.config, realm es el enlace a mi aplicación web (https: //ssoadfs.test) y adfsMetadata es el enlace a metadata.xml de AD FS.

¿Cuál es el camino a seguir para establecer mi función y lógica de inicio de sesión después de la conexión AD FS?

Esquema de lo que estaba pensando:

EDITAR: después de algunos intentos, no puedo manejar ninguna devolución de llamada exitosa. No quiero tener que manejar roles en HomeController ...

Mi última configuración de autenticación:

            _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);
                    }
                }
            });

En este código, probé CallbackPath (no apareció nada en mi registro), WsFederationAuthenticationNotifications.SecurityTokenValidated (no apareció nada en mi registro), CookieAuthenticationProvider.OnResponseSignIn (no pasó nada)

En HomeController puedo tener Identity.Name:

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

        return View();
    }

¿Me perdí algo para que funcionen las notificaciones o el proveedor en CookieAuthenticationOptions ???

Respuestas a la pregunta(1)

Su respuesta a la pregunta