/// <summary>
 ///     Validates that UserNames are unique and case insenstive
 /// </summary>
 /// <param name="entityEntry"></param>
 /// <param name="items"></param>
 /// <returns></returns>
 protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry,
                                                            IDictionary <object, object> items)
 {
     if (entityEntry != null && entityEntry.State == EntityState.Added)
     {
         var errors = new List <DbValidationError>();
         var user   = entityEntry.Entity as ApiUser;
         //check for uniqueness of user name and email
         if (user != null)
         {
             if (IdentityUsers.Any(u => String.Equals(u.UserName, user.UserName)))
             {
                 errors.Add(new DbValidationError("User",
                                                  String.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateUserName, user.UserName)));
             }
             if (RequireUniqueEmail && IdentityUsers.Any(u => String.Equals(u.Email, user.Email)))
             {
                 errors.Add(new DbValidationError("User",
                                                  String.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateEmail, user.Email)));
             }
         }
         else
         {
             var role = entityEntry.Entity as IdentityRole;
             //check for uniqueness of role name
             if (role != null && Roles.Any(r => String.Equals(r.Name, role.Name)))
             {
                 errors.Add(new DbValidationError("Role",
                                                  String.Format(CultureInfo.CurrentCulture, IdentityResources.RoleAlreadyExists, role.Name)));
             }
         }
         if (errors.Any())
         {
             return(new DbEntityValidationResult(entityEntry, errors));
         }
     }
     return(base.ValidateEntity(entityEntry, items));
 }
        public void Configuration(IAppBuilder app)
        {
            AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject;
            JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary <string, string>();

            Common.Logging.Logger.Initialize(HostingEnvironment.ApplicationPhysicalPath + "errorLog.config");

            app.MapSignalR();

            app.Map(
                pathMatch: "/identity",
                configuration: idsrvApp =>
            {
                idsrvApp.UseIdentityServer(
                    new IdentityServerOptions
                {
                    SiteName           = "Embedded IdentityServer",
                    SigningCertificate = LoadCertificate(),

                    Factory = new IdentityServerServiceFactory()
                              .UseInMemoryUsers(IdentityUsers.Get())
                              .UseInMemoryClients(IdentityClients.Get())
                              .UseInMemoryScopes(IdentityScopes.Get()),

                    AuthenticationOptions = new IdentityServer3.Core.Configuration.AuthenticationOptions
                    {
                        IdentityProviders = ConfigureIdentityProviders
                    }
                });
            });

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies"
            });

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                Authority    = "https://localhost:44392/identity",
                ClientId     = "mvc",
                Scope        = "openid profile roles sampleApi",
                RedirectUri  = "https://localhost:44392/",
                ResponseType = "id_token token",

                SignInAsAuthenticationType = "Cookies",
                UseTokenLifetime           = false,

                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    SecurityTokenValidated = async n =>
                    {
                        // create new identity and set name and role claim type
                        var nid = new ClaimsIdentity(
                            n.AuthenticationTicket.Identity.AuthenticationType,
                            Constants.ClaimTypes.GivenName,
                            Constants.ClaimTypes.Role);

                        // get userinfo data
                        var userInfoClient = new UserInfoClient(n.Options.Authority + "/connect/userinfo");

                        var userInfo = await userInfoClient.GetAsync(n.ProtocolMessage.AccessToken);
                        userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Type, ui.Value)));

                        nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

                        // add access token for sample API
                        nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));

                        // keep track of access token expiration
                        nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString()));

                        // add some other app specific claim
                        ////nid.AddClaim(new Claim("app_specific", "some data"));

                        n.AuthenticationTicket = new AuthenticationTicket(
                            nid,
                            n.AuthenticationTicket.Properties);
                    },
                    RedirectToIdentityProvider = n =>
                    {
                        if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                        {
                            var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                            if (idTokenHint != null)
                            {
                                n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                            }
                        }

                        return(Task.FromResult(0));
                    }
                }
            });
        }