示例#1
0
        public void AuthenticateWithEmptyToken()
        {
            //-- Arrange
            var userName = "******";
            var password = "******";
            var roles    = new string[] { "Tester" };
            var token    = string.Empty;

            var externalAuthorization = new ExternalAuthenticator()
            {
                Token = token
            };

            authService.ExternalAuthorization = externalAuthorization;

            authService.UserRepository.Create(userName, new UserData(userName, password, roles.ToList()));

            authService.AuthenticateUser(userName, password);

            authService.ExternalAuthorization.RequestTokenChange();

            authService.DeAuthenticateCurrentUser();

            externalAuthorization.Token = string.Empty;


            authService.ExternalAuthorization.RequestAuthorization();

            AppPrincipal customPrincipal = Thread.CurrentPrincipal as AppPrincipal;

            Assert.AreEqual(string.Empty, customPrincipal.Identity.Name);
            Assert.AreEqual(0, customPrincipal.Identity.Roles.Length);
            Assert.AreEqual(string.Empty, customPrincipal.Identity.Level);
        }
        public async Task CreateTokenWithNullAppPrincipal()
        {
            AppPrincipal  appPrincipal  = null;
            UserPrincipal userPrincipal = new UserPrincipal(this.managersContext.Log, "genericUserHandle", IdentityProviderType.AADS2S, "genericUserHandle");

            await this.managersContext.SessionTokenManager.CreateToken(appPrincipal, userPrincipal, TimeSpan.FromTicks(1));
        }
        /// <summary>
        /// Create SocialPlus session token
        /// </summary>
        /// <param name="appPrincipal">app principal (cannot be null)</param>
        /// <param name="userPrincipal">user principal (cannot be null)</param>
        /// <param name="duration">lifetime of the token</param>
        /// <returns>SocialPlus session token</returns>
        public async Task <string> CreateToken(AppPrincipal appPrincipal, UserPrincipal userPrincipal, TimeSpan duration)
        {
            // If init not called, call init.
            if (this.initStarted == false)
            {
                await this.Init();
            }

            if (appPrincipal == null || userPrincipal == null)
            {
                throw new ArgumentNullException(
                          string.Format(
                              "CreateToken constructor can't take null parameters. appPrincipal: {0}, userPrincipal: {1}",
                              appPrincipal,
                              userPrincipal));
            }

            if (this.signingKey == null)
            {
                throw new InvalidOperationException("Token manager has a null signing key and thus cannot create tokens.");
            }

            // A session token has two claims: an app principal claim and a user principal claim
            Claim[] claims = new Claim[1] {
                this.GenerateUserClaim(userPrincipal)
            };

            // A token descriptor is like a legend of what the token should include
            var tokenDescriptor = this.GenerateSessionTokenDescriptor(appPrincipal, claims, duration);

            // Using the token descriptor, we are ready to generate and return the token
            var token = this.tokenHandler.CreateToken(tokenDescriptor);

            return(this.tokenHandler.WriteToken(token));
        }
        /// <summary>
        /// Returns whether the current data context can currently be saved to the store.
        /// </summary>
        bool ISaveable.CanSave(AppPrincipal contextUser, IList <ErrorResult> errors)
        {
            bool result = false;

            if (_validator != null)
            {
                if (_validator.CanAssertAuthorizations)
                {
                    _validator.AssertAuthorizations(contextUser, this.AppContext, this);
                }

                if (_validator.CanValidate)
                {
                    result = _validator.Validate(contextUser, this.AppContext, this, errors);
                }
                else
                {
                    result = true;
                }
            }
            else
            {
                result = true;
            }

            return(result);
        }
        public async Task CreateTokenWithNullUserPrincipal()
        {
            AppPrincipal  appPrincipal  = new AppPrincipal("genericAppHandle", "genenericAppKey");
            UserPrincipal userPrincipal = null;

            await this.managersContext.SessionTokenManager.CreateToken(appPrincipal, userPrincipal, TimeSpan.FromTicks(1));
        }
示例#6
0
        /// <summary>
        /// Validate the data in the specified entity framework context.
        /// </summary>
        public bool Validate(AppPrincipal contextPrincipal, AppContextBase appContext, T dataContext, IList <ErrorResult> errors)
        {
            bool result = true;

            if (this.CanValidateUsingDataAnnotations)
            {
                foreach (object entity in dataContext.GetChanges())
                {
                    var validatationContext      = new ValidationContext(entity, serviceProvider: null, items: null);
                    var volidationContextResults = new List <ValidationResult>();

                    result = Validator.TryValidateObject(entity, validatationContext, volidationContextResults, true);

                    foreach (ValidationResult error in volidationContextResults)
                    {
                        errors.Add(new ErrorResult(ErrorResultKind.Validation, error.ErrorMessage));
                    }
                }
            }

            foreach (Validation validation in this.Validations)
            {
                foreach (object entity in dataContext.GetChanges(validation.Type))
                {
                    if (!validation.Validate(contextPrincipal, appContext, dataContext.Data, entity, errors))
                    {
                        result = false;
                    }
                }
            }

            return(result);
        }
        public async Task ValidateProperToken()
        {
            AppPrincipal  appPrincipal  = new AppPrincipal("genericAppHandle", "genenericAppKey");
            UserPrincipal userPrincipal = new UserPrincipal(this.managersContext.Log, "genericUserHandle", IdentityProviderType.AADS2S, "genericUserHandle");
            string        token         = await this.managersContext.SessionTokenManager.CreateToken(appPrincipal, userPrincipal, TimeSpan.FromMinutes(1));

            var principals = await this.managersContext.SessionTokenManager.ValidateToken(token);

            // Extract app and user principals from session token.
            AppPrincipal  sessionTokenAppPrincipal  = null;
            UserPrincipal sessionTokenUserPrincipal = null;

            foreach (IPrincipal p in principals)
            {
                if (p is AppPrincipal)
                {
                    sessionTokenAppPrincipal = p as AppPrincipal;
                }
                else
                {
                    sessionTokenUserPrincipal = p as UserPrincipal;
                }
            }

            Assert.AreEqual(appPrincipal, sessionTokenAppPrincipal);
            Assert.AreEqual(userPrincipal, sessionTokenUserPrincipal);
        }
        public async Task ValidateExpiredToken()
        {
            AppPrincipal  appPrincipal           = new AppPrincipal("genericAppHandle", "genenericAppKey");
            UserPrincipal userPrincipal          = new UserPrincipal(this.managersContext.Log, "genericUserHandle", IdentityProviderType.AADS2S, "genericUserHandle");
            string        tokenWithShortLifetime = await this.managersContext.SessionTokenManager.CreateToken(appPrincipal, userPrincipal, TimeSpan.FromTicks(1));

            await this.managersContext.SessionTokenManager.ValidateToken(tokenWithShortLifetime);
        }
        public void SerializeDeserializeAppPrincipal()
        {
            AppPrincipal appPrincipal             = new AppPrincipal("genericAppHandle", "genericAppKey");
            string       serializedAppPrincipal   = appPrincipal.ToString();
            AppPrincipal deserializedAppPrincipal = new AppPrincipal(serializedAppPrincipal);

            Assert.AreEqual(appPrincipal.AppHandle, deserializedAppPrincipal.AppHandle);
            Assert.AreEqual(appPrincipal.AppKey, deserializedAppPrincipal.AppKey);
        }
        public void ShouldGetDifferentImplementationFromResolveContextForUser()
        {
            IIdentity identity = new AppIdentity();
            // three principals, one for each role
            var adminPrincipal    = new AppPrincipal(identity, new[] { "Admin" });
            var salesPrincipal    = new AppPrincipal(identity, new[] { "Sales" });
            var customerPrincipal = new AppPrincipal(identity, new[] { "Customer" });

            var container = new Container();

            container.RegisterType <AdminActionsService>();
            container.RegisterType <SalesActionsService>();
            container.RegisterType <CustomerActionsService>();
            container.RegisterType <UserControlPanel>();
            // register delegate to read the CurrentPrincipal property, to make it dynamic
            container.RegisterDelegate(() => CurrentPrincipal);
            // now register the delegate handler for the IUserActionsService, which does the
            // role sniffing over the principal
            container.RegisterDelegate((IPrincipal p, ResolveContext rc) => {
                IUserActionsService toReturn = null;
                if (p != null)
                {
                    if (p.IsInRole("Customer"))
                    {
                        toReturn = rc.Resolve <CustomerActionsService>();
                    }
                    else if (p.IsInRole("Sales"))
                    {
                        toReturn = rc.Resolve <SalesActionsService>();
                    }
                    else if (p.IsInRole("Admin"))
                    {
                        toReturn = rc.Resolve <AdminActionsService>();
                    }
                }
                return(toReturn);
            });

            // set the principal, and resolve
            CurrentPrincipal = adminPrincipal;
            var result1 = container.Resolve <UserControlPanel>();

            // now swap principals
            CurrentPrincipal = salesPrincipal;
            var result2 = container.Resolve <UserControlPanel>();

            // and again
            CurrentPrincipal = customerPrincipal;
            var result3 = container.Resolve <UserControlPanel>();

            Assert.IsType <AdminActionsService>(result1.ActionsService);
            Assert.IsType <SalesActionsService>(result2.ActionsService);
            Assert.IsType <CustomerActionsService>(result3.ActionsService);
        }
        /// <summary>
        /// Method that generates the token descriptor of a SocialPlus session token
        /// </summary>
        /// <param name="appPrincipal">app principal</param>
        /// <param name="claims">token's claims</param>
        /// <param name="duration">lifetime of the token</param>
        /// <returns>token descriptor</returns>
        private SecurityTokenDescriptor GenerateSessionTokenDescriptor(AppPrincipal appPrincipal, Claim[] claims, TimeSpan duration)
        {
            var now = DateTime.UtcNow;

            return(new SecurityTokenDescriptor
            {
                TokenIssuerName = appPrincipal.ToString(),
                Subject = new ClaimsIdentity(claims),
                Lifetime = new Lifetime(null, now.Add(duration)),
                SigningCredentials = new SigningCredentials(this.signingKey, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest),
            });
        }
        /// <summary>
        /// Commit changes to any store in the context that supports it.
        /// </summary>
        public virtual async Task <bool> SaveChangesAsync(AppPrincipal contextUser, Type sharedDataObjectType, bool assertSuccess = false)
        {
            bool result = false;

            List <ErrorResult> errors = new List <ErrorResult>();
            OptionsDictionary <Type, object> results = new OptionsDictionary <Type, object>();
            List <KeyValuePair <Type, SharedObjectEntry> > sharedObjects = _sharedObjects
                                                                           .Where(o => (sharedDataObjectType == null || o.Key == sharedDataObjectType) && o.Value.Value != null && o.Value.Value is ISaveable)
                                                                           .OrderBy(o => o.Value.Index).ToList();

            bool canSave = true;

            foreach (KeyValuePair <Type, SharedObjectEntry> sharedObject in sharedObjects)
            {
                canSave = (sharedObject.Value.Value as ISaveable).CanSave(contextUser, errors);

                if (!canSave)
                {
                    break;
                }
            }

            _lastSaveErrors = errors;

            if (canSave)
            {
                foreach (KeyValuePair <Type, SharedObjectEntry> sharedObject in sharedObjects)
                {
                    canSave = (sharedObject.Value.Value as ISaveable).CanSave(contextUser, errors);

                    if (!canSave)
                    {
                        break;
                    }

                    object saveResult = await((ISaveable)sharedObject.Value.Value).SaveAsync(contextUser);

                    results.Add(sharedObject.Key, saveResult);
                }

                result = true;
            }

            _lastSaveResults = results;

            if (assertSuccess)
            {
                AssertSaveSuccess(result);
            }

            return(result);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SessionsController"/> class
 /// </summary>
 /// <param name="managersContext">managers context</param>
 /// <param name="principalsContext">principals context</param>
 public SessionsController(ManagersContext managersContext, PrincipalsContext principalsContext)
     : base(
         managersContext.Log,
         managersContext.IdentitiesManager,
         managersContext.SessionTokenManager,
         managersContext.UsersManager,
         managersContext.AppsManager,
         managersContext.ApplicationMetrics)
 {
     this.appPrincipal  = principalsContext.AppPrincipal;
     this.userPrincipal = principalsContext.UserPrincipal;
     this.guid          = Guid.NewGuid();
 }
示例#14
0
 public bool Login(string userId, string password)
 {
     try
     {
         string hashed = PhpCompatible.Md5Hash(password);
         return(AppPrincipal.Login(userId, hashed));
     }
     catch (Exception ex)
     {
         log.ErrorFormat("Login -> Message: {0}", ex.Message);
         log.ErrorFormat("Login -> StackTrace: {0}", ex.StackTrace);
         return(false);
     }
 }
示例#15
0
        /// <summary>
        /// Validate authorization header.
        /// The SocialPlus auth header must include a token. This token is our own session token that includes an app and a user principal
        /// This method:
        ///     - validates the token
        ///     - validates the app principal
        ///     - validates the user principal
        /// </summary>
        /// <param name="authParameter">authorization parameter</param>
        /// <returns>list of principals</returns>
        public async Task <List <IPrincipal> > ValidateAuthParameter(string authParameter)
        {
            string token;

            // Parse the authorization header
            var authDictionary = new Dictionary <string, string>();

            this.ParseAuthParameter(authParameter, authDictionary);

            // Get the token and validate it.
            authDictionary.TryGetValue("tk", out token);
            var principals = await this.sessionTokenManager.ValidateToken(token);

            // Before returning the principals, we must validate them
            AppPrincipal  appPrincipal  = null;
            UserPrincipal userPrincipal = null;

            foreach (var p in principals)
            {
                if (p is AppPrincipal)
                {
                    appPrincipal = p as AppPrincipal;
                }
                else
                {
                    userPrincipal = p as UserPrincipal;
                }
            }

            // Fire the validation tasks in parallel
            var task1 = this.ValidateAppKey(appPrincipal.AppKey);
            var task2 = this.ValidateUserPrincipal(userPrincipal, appPrincipal.AppHandle);
            await Task.WhenAll(task1, task2);

            // Is app key valid?
            if (task1.Result == false)
            {
                string errorMessage = $"Invalid AppKey. AppPrincipal={appPrincipal.ToString()}";
                this.Log.LogException(errorMessage);
            }

            // Is user principal valid?
            if (task2.Result == false)
            {
                string errorMessage = $"Invalid UserPrincipal. UserPrincipal={userPrincipal.ToString()}, AppHandle={appPrincipal.AppHandle}";
                this.Log.LogException(errorMessage);
            }

            return(principals);
        }
        /// <summary>
        /// Commits the current data context to the store.
        /// </summary>
        async Task <object> ISaveable.SaveAsync(AppPrincipal contextUser)
        {
            object result = null;

            PrepareChangedCollections();

            result = await this.Data.SaveChangesAsync();

            if (_validator != null && _validator.CanAudit)
            {
                _validator.Audit(contextUser, this.AppContext, this);
            }

            return(result);
        }
示例#17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MyLinkedAccountsController"/> class
 /// </summary>
 /// <param name="managersContext">managers context</param>
 /// <param name="principalsContext">principals context</param>
 public MyLinkedAccountsController(ManagersContext managersContext, PrincipalsContext principalsContext)
     : base(
         managersContext.Log,
         managersContext.IdentitiesManager,
         managersContext.UsersManager,
         managersContext.AppsManager,
         managersContext.ViewsManager,
         managersContext.SessionTokenManager)
 {
     this.appPrincipal    = principalsContext.AppPrincipal;
     this.userPrincipal   = principalsContext.UserPrincipal;
     this.guid            = Guid.NewGuid();
     this.handleGenerator = managersContext.HandleGenerator;
     this.log             = managersContext.Log;
 }
示例#18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TopicsController"/> class
 /// </summary>
 /// <param name="managersContext">managers context</param>
 /// <param name="principalsContext">principals context</param>
 public TopicsController(ManagersContext managersContext, PrincipalsContext principalsContext)
     : base(
         managersContext.Log,
         managersContext.UsersManager,
         managersContext.TopicsManager,
         managersContext.AppsManager,
         managersContext.PopularTopicsManager,
         managersContext.ViewsManager,
         managersContext.TopicNamesManager,
         managersContext.HandleGenerator)
 {
     this.appPrincipal  = principalsContext.AppPrincipal;
     this.userPrincipal = principalsContext.UserPrincipal;
     this.guid          = Guid.NewGuid();
 }
示例#19
0
        /// <summary>
        /// Check changed entities and assert authorizations.
        /// </summary>
        public void AssertAuthorizations(AppPrincipal contextPrincipal, AppContextBase appContext, T dataContext)
        {
            foreach (Authorization authorization in this.Authorizations)
            {
                foreach (object entity in dataContext.GetChanges(authorization.Type))
                {
                    appContext.AssertAuthorization(authorization.Authorize(contextPrincipal, appContext, dataContext.Data, entity));
                }
            }

            foreach (Type type in this.ReadOnlyTypes)
            {
                appContext.AssertAuthorization(!dataContext.GetChanges(type).Any());
            }
        }
示例#20
0
        /// <summary>
        /// Audit changes in the specified entity framework context.
        /// </summary>
        public void Audit(AppPrincipal contextPrincipal, AppContextBase appContext, T dataContext)
        {
            try
            {
                ItemIdentifier userIdentifier = new ItemIdentifier(contextPrincipal.UserInfo.Id, contextPrincipal.UserInfo.Oid, contextPrincipal.UserInfo.UserName);

                appContext.AuditLogger.LogActions(AppAuditAction.Delete, 0, userIdentifier, this.AuditTypes, dataContext.GetLastDeleted(), null);
                appContext.AuditLogger.LogActions(AppAuditAction.Add, 0, userIdentifier, this.AuditTypes, dataContext.GetLastAdded(), null);
                appContext.AuditLogger.LogActions(AppAuditAction.Modify, 0, userIdentifier, this.AuditTypes, dataContext.GetLastModified(), null);
            }
            catch (Exception ex)
            {
                appContext.ErrorLogger.LogError(ex, "Could not complete logging of audit actions.", 0, 0, contextPrincipal.UserInfo.Id, contextPrincipal.UserInfo.Oid, contextPrincipal.UserInfo.UserName);
                throw;
            }
        }
示例#21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MyFollowingController"/> class
 /// </summary>
 /// <param name="managersContext">managers context</param>
 /// <param name="principalsContext">principals context</param>
 /// <param name="authHeader">authentication header</param>
 public MyFollowingController(ManagersContext managersContext, PrincipalsContext principalsContext, string authHeader)
     : base(
         managersContext.Log,
         managersContext.RelationshipsManager,
         managersContext.UsersManager,
         managersContext.TopicsManager,
         managersContext.ActivitiesManager,
         managersContext.ViewsManager,
         managersContext.AuthManager,
         managersContext.HandleGenerator)
 {
     this.appPrincipal  = principalsContext.AppPrincipal;
     this.userPrincipal = principalsContext.UserPrincipal;
     this.guid          = Guid.NewGuid();
     this.authHeader    = authHeader;
 }
        /// <summary>
        /// Creates an authentication ticket with the specified properties
        /// </summary>
        /// <param name="keepLoggedIn">Keep the user logged in</param>
        /// <param name="userId">User ID</param>
        /// <param name="userName">User name</param>
        /// <param name="isServiceUser">Is this user a service user?</param>
        /// <param name="subscriptionId">Optional subscription ID</param>
        /// <param name="isSubscriptionOwner">Is this user a subscription owner?</param>
        public void CreateAuthenticationTicket(bool keepLoggedIn, Guid userId, string userName, bool isServiceUser,
                                               int?subscriptionId, bool isSubscriptionOwner)
        {
            var appPrincipal = new AppPrincipal(userId, userName, isServiceUser, subscriptionId, isSubscriptionOwner,
                                                null);
            var jsonTicket = appPrincipal.Serialize();
            var authTicket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddHours(24), true, jsonTicket);
            var encTicket  = FormsAuthentication.Encrypt(authTicket);
            var faCookie   = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);

            if (keepLoggedIn)
            {
                faCookie.Expires = DateTime.Now.AddDays(14);
            }
            Response.Cookies.Add(faCookie);
        }
        public void ShouldGetDifferentImplementationFromResolveContextForUser()
        {
            // this test is functionally identical to the one in DelegateExamples.cs,
            // it's just done with an expression, and therefore the format of the code block
            // used for the IUserActionsService is different because the compiler can only
            // translate expression lambdas.
            IIdentity identity = new AppIdentity();
            // three principals, one for each role
            var adminPrincipal    = new AppPrincipal(identity, new[] { "Admin" });
            var salesPrincipal    = new AppPrincipal(identity, new[] { "Sales" });
            var customerPrincipal = new AppPrincipal(identity, new[] { "Customer" });

            var container = new Container();

            container.RegisterType <AdminActionsService>();
            container.RegisterType <SalesActionsService>();
            container.RegisterType <CustomerActionsService>();
            container.RegisterType <UserControlPanel>();
            // register expression to read the CurrentPrincipal property, to make it dynamic
            container.RegisterExpression(() => CurrentPrincipal);
            // now register the expression for the IUserActionsService, which does the
            // role sniffing over the principal as one expression
            container.RegisterExpression((IPrincipal p, ResolveContext rc) =>
                                         p.IsInRole("Customer") ?
                                         rc.Resolve <CustomerActionsService>() :
                                         p.IsInRole("Sales") ?
                                         rc.Resolve <SalesActionsService>() :
                                         p.IsInRole("Admin") ?
                                         rc.Resolve <AdminActionsService>() :
                                         (IUserActionsService)null);

            // set the principal, and resolve
            CurrentPrincipal = adminPrincipal;
            var result1 = container.Resolve <UserControlPanel>();

            // now swap principals
            CurrentPrincipal = salesPrincipal;
            var result2 = container.Resolve <UserControlPanel>();

            // and again
            CurrentPrincipal = customerPrincipal;
            var result3 = container.Resolve <UserControlPanel>();

            Assert.IsType <AdminActionsService>(result1.ActionsService);
            Assert.IsType <SalesActionsService>(result2.ActionsService);
            Assert.IsType <CustomerActionsService>(result3.ActionsService);
        }
示例#24
0
 protected override Task InitializeCoreAsync()
 {
     if (Request.User?.Identity is ClaimsIdentity)
     {
         var appPrincipal = new AppPrincipal(Request.User.Identity);
         var ticket       = GetAuthenticationTicket();
         if (ticket?.Identity != null)
         {
             var userWrap = new CurrentUserWrap
             {
                 LoginIp         = ticket.Properties.Dictionary[LoginIp],
                 LoginTime       = Convert.ToDateTime(ticket.Properties.Dictionary[LoginTime]),
                 ClaimsPrincipal = appPrincipal
             };
             appPrincipal.Identity.UserInfo = userWrap;
         }
         Request.User            = appPrincipal;
         Thread.CurrentPrincipal = appPrincipal;
     }
     return(Task.FromResult <object>(null));
 }
示例#25
0
        public async Task <AppPrincipal> CreatePrincipal(IKeyValueSettings settings, Messages messages, object parameter = null)
        {
            Identity = new ClaimsIdentity("OAuth2Bearer", System.Security.Claims.ClaimTypes.Upn, ClaimsIdentity.DefaultRoleClaimType);

            if (null == settings)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            if (null == messages)
            {
                throw new ArgumentNullException(nameof(messages));
            }

            /// when we have no internet connectivity may be we have claims in cache.
            if (NetworkStatus.None == NetworkInformation.Status)
            {
                // In a scenario where the claims cached are always for one user like a UI, the identity is not used => so retrieving the claims in the cache is possible!
                var identity = new ClaimsIdentity();
                cachedClaims = GetClaimsFromCache(identity);
                Identity.AddClaims(cachedClaims.Select(p => new Claim(p.ClaimType, p.Value)));
                messages.Add(new Message(ServiceModel.MessageCategory.Technical, ServiceModel.MessageType.Information, "Create the principal from the cache due to no network connectivity."));
            }
            else
            {
                await BuildTheIdentity(settings, messages, parameter);
            }

            var authorization = BuildAuthorization(settings, messages);
            var user          = BuildProfile(settings, messages);

            var principal = new AppPrincipal(authorization, Identity, null)
            {
                Profile = user
            };

            ApplicationContext.SetPrincipal(principal);

            return(principal);
        }
        /// <summary>
        /// Construct the principals context from an app key only. A user principal will be constructed by default
        /// </summary>
        /// <param name="managersContext">managers context</param>
        /// <param name="appKey">app key</param>
        /// <param name="identityProviderType">identity provider type (defaults to Twitter)</param>
        /// <param name="userPrincipal">user principal</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public static async Task <PrincipalsContext> ConstructPrincipalsContext(ManagersContext managersContext, string appKey, IdentityProviderType identityProviderType = IdentityProviderType.Twitter, UserPrincipal userPrincipal = null)
        {
            // Read app profile
            var appLookupEntity = await managersContext.AppsManager.ReadAppByAppKey(appKey);

            if (appLookupEntity == null)
            {
                throw new InvalidOperationException("No app key found in our tables.");
            }

            // App principal is ready to be created
            var appPrincipal = new AppPrincipal(appLookupEntity.AppHandle, appKey);

            // Create user principal if the one passed in is null.
            if (userPrincipal == null)
            {
                string userHandle = managersContext.HandleGenerator.GenerateShortHandle();
                string accountId  = managersContext.HandleGenerator.GenerateShortHandle();
                userPrincipal = new UserPrincipal(managersContext.Log, userHandle, identityProviderType, accountId);
            }

            return(new PrincipalsContext(appPrincipal, userPrincipal));
        }
示例#27
0
        public async Task RefreshIdentity(AppPrincipal principal, bool reloadClaims = false)
        {
            ClaimsIdentity identity = null;

            var isPersistent = principal.IsPersistent;

            if (reloadClaims)
            {
                var adminUser = await _userManager.FindByIdAsync(principal.Id);

                if (adminUser != null)
                {
                    identity = await adminUser.GenerateUserIdentityAsync(
                        _userManager,
                        isPersistentState : isPersistent,
                        screenLockedState : false
                        );
                }
            }
            else
            {
                identity = principal.Identity as ClaimsIdentity;
            }

            if (identity == null)
            {
                throw new Exception("The provided principal has an invalid identity.", new Exception(nameof(RefreshIdentity)));
            }

            AuthenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(
                identity,
                new AuthenticationProperties {
                IsPersistent = isPersistent
            }
                );
        }
示例#28
0
        public async Task Invoke(HttpContext context)
        {
            // Get the scoped instance of the container!
            IContainerResolve container = (IContainerResolve)context.RequestServices.GetService(typeof(IContainerResolve));
            var logger = container.Resolve <ILogger <ClaimsPrincipalMiddleware> >();

            try
            {
                // if we have some part of the site not in MVC (like swagger) and we need to force
                // authentication. We can add the start of the path to check and in this case we force a login!
                if (null != context.User && !context.User.Identity.IsAuthenticated)
                {
                    if (_option.OpenIdOptions.ForceAuthenticationForPaths.Any(r =>
                    {
                        return(r.Last().Equals('*') ?
                               context.Request.Path.Value.StartsWith(r.Remove(r.Length - 1), StringComparison.InvariantCultureIgnoreCase)
                            :
                               context.Request.Path.Value.Equals(r, StringComparison.InvariantCultureIgnoreCase));
                    }))
                    {
                        logger.Technical().System("Force an OpenId connection.").Log();
                        var cleanUri = new Uri(new Uri(context.Request.GetEncodedUrl()).GetLeftPart(UriPartial.Path));
                        if (Uri.TryCreate(_option.RedirectAuthority, UriKind.Absolute, out var authority))
                        {
                            cleanUri = new Uri(authority, cleanUri.AbsolutePath);
                        }
                        var properties = new AuthenticationProperties()
                        {
                            RedirectUri = cleanUri.ToString()
                        };
                        await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, properties);

                        return;
                    }
                }

                if (null != context.User && context.User.Identity.IsAuthenticated)
                {
                    logger.Technical().System("Create the principal.").Log();

                    // Add Telemetry.
                    using (var activity = _activitySource?.StartActivity("Create Arc4u Principal", ActivityKind.Producer))
                    {
                        // As the extension point can use some ITokenProvider based on the user.
                        // A dummy Principal is created based on the context identity!
                        // Must be registered as Scoped!
                        if (container.TryResolve <IApplicationContext>(out var applicationContext))
                        {
                            applicationContext.SetPrincipal(new AppPrincipal(new Authorization(), context.User.Identity, "S-1-0-0"));
                        }

                        // Load Claims from an external source if necessary!
                        if (_option.ClaimsFillerOptions.LoadClaimsFromClaimsFillerProvider)
                        {
                            await LoadExtraClaimsAsync(context, container, logger);
                        }

                        // Build an AppPrincipal.
                        AppPrincipal principal           = null;
                        var          profileFiller       = container.Resolve <IClaimProfileFiller>();
                        var          authorizationFiller = container.Resolve <IClaimAuthorizationFiller>();

                        var authorization = authorizationFiller.GetAuthorization(context.User.Identity);
                        var profile       = profileFiller.GetProfile(context.User.Identity);
                        principal = new AppPrincipal(authorization, context.User.Identity, profile.Sid)
                        {
                            Profile = profile
                        };

                        // Check if we have an ActivityID.
                        var activityIdHeader = context.Request?.Headers?.FirstOrDefault(h => h.Key.Equals("activityid", StringComparison.InvariantCultureIgnoreCase));

                        if (null == activityIdHeader || !activityIdHeader.HasValue || String.IsNullOrWhiteSpace(activityIdHeader.Value.Key) || StringValues.Empty == activityIdHeader.Value || activityIdHeader.Value.Value.Count == 0)
                        {
                            principal.ActivityID = Guid.NewGuid();
                        }
                        else
                        {
                            Guid activityId = Guid.Empty;
                            if (Guid.TryParse(activityIdHeader.Value.Value[0], out activityId) && activityId != Guid.Empty)
                            {
                                logger.Technical().Information($"Set the activity to the principal based on the caller information: {activityId}.").Log();
                            }
                            else
                            {
                                logger.Technical().Information($"The activity id given by the caller is not a valid Guid. A new one has been assigned.").Log();
                                activityId = Guid.NewGuid();
                            }

                            principal.ActivityID = activityId;
                        }
                        activity?.AddTag(LoggingConstants.ActivityId, principal.ActivityID);
                        // Check for a culture.
                        var cultureHeader = context.Request?.Headers?.FirstOrDefault(h => h.Key.Equals("culture", StringComparison.InvariantCultureIgnoreCase));
                        if (null != cultureHeader && cultureHeader.HasValue && StringValues.Empty != activityIdHeader.Value && cultureHeader.Value.Value.Count > 0)
                        {
                            try
                            {
                                principal.Profile.CurrentCulture = new CultureInfo(cultureHeader.Value.Value[0]);
                            }
                            catch (Exception ex)
                            {
                                logger.Technical().Exception(ex).Log();
                            }
                        }
                        logger.Technical().System("Set AppPrincipal to the HttpContext.User.").Log();
                        context.User = principal;

                        if (null != applicationContext)
                        {
                            logger.Technical().System("Set AppPrincipal to the ApplicationContext.").Log();
                            applicationContext.SetPrincipal(principal);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Technical().Exception(ex).Log();
            }

            await _next(context);
        }
        private Container ConfigureDependencyInjectionContainer(IAppBuilder appBuilder)
        {
            var container        = GetContainer();
            var domainAssemblies = GetKnownDomainAssemblies();

            //
            container.Register <AppUserStore>();
            container.Register <AppUserManager>();
            container.Register <AppSignInManager>();
            container.Register(() => appBuilder.GetDataProtectionProvider());

            container.Register(() =>
            {
                if (AdvancedExtensions.IsVerifying(container) || HttpContext.Current == null)
                {
                    return(new OwinContext().Authentication);
                }

                return(HttpContext.Current.GetOwinContext().Authentication);
            });

            //
            var cloudName                  = AppSettings.Cloudinary.CloudName;
            var cloudApiKey                = AppSettings.Cloudinary.CloudApiKey;
            var cloudApiSecret             = AppSettings.Cloudinary.CloudApiSecret;
            var azureBlobsConnection       = AppSettings.Azure.BlobsConnection;
            var azureBlobsDefaultContainer = AppSettings.Azure.BlobsDefaultContainer;
            var fileSystemStorageFolder    = AppSettings.FileSystem.StorageFolder;
            var activeStorageService       = AppSettings.ActiveStorageService;

            var cloudinaryStorage = Lifestyle.Singleton.CreateRegistration <IBlobStorageService>(
                () => new CloudinaryStorageService(cloudName, cloudApiKey, cloudApiSecret), container);

            var azureBlobsStorage = Lifestyle.Singleton.CreateRegistration <IAzureStorageService>(
                () => new AzureStorageService(azureBlobsConnection, azureBlobsDefaultContainer), container);

            var fileSystemStorage = Lifestyle.Singleton.CreateRegistration <IBlobStorageService>(
                () => new FileSystemStorageService(fileSystemStorageFolder), container);

            container.RegisterConditional(typeof(IBlobStorageService), cloudinaryStorage, context => "cloudinary".Equals(activeStorageService));
            container.RegisterConditional(typeof(IBlobStorageService), azureBlobsStorage, context => "azurestorage".Equals(activeStorageService));
            container.RegisterConditional(typeof(IBlobStorageService), fileSystemStorage, context => !context.Handled);             // Defaults to filesystem

            var cloudinaryThumbService = Lifestyle.Singleton.CreateRegistration <ICloudinaryThumbService>(
                () => new CloudinaryThumbService(cloudName), container);

            var imageResizerThumbService = Lifestyle.Singleton.CreateRegistration <IImageResizerThumbService>(
                () => new ImageResizerThumbService(), container);

            container.RegisterConditional(typeof(IBlobThumbService), cloudinaryThumbService, context => "cloudinary".Equals(activeStorageService));
            container.RegisterConditional(typeof(IBlobThumbService), imageResizerThumbService, context => !context.Handled);             // Defaults to image resizer

            //
            var connectionString = WebConfigurationManager.ConnectionStrings["SqlServerConnection"].ConnectionString;

            container.Register <IDbConnectionFactory>(() => new SqlConnectionFactory(connectionString));

            container.Register <IBlobsRepository, BlobsRepository>();
            container.Register <ILogsRepository, LogsRepository>();

            container.Register <IIdentityRepository, IdentityRepository>();
            container.Register <IUsersRepository, UsersRepository>();

            //
            var mailGunApiKey      = AppSettings.MailGun.ApiKey;
            var mailGunDomainName  = AppSettings.MailGun.DomainName;
            var defaultFromAddress = new MailAddress(
                AppSettings.Emails.DefaultEmailFromAddress,
                AppSettings.Emails.DefaultEmailFromDisplayName
                );
            var activeEmailDispatcherService = AppSettings.ActiveEmailDispatcherService;

            var mailGunDispatcherService = container.Options.DefaultLifestyle.CreateRegistration <IMailGunApiEmailDispatcherService>(
                () => new MailGunApiEmailDispatcherService(mailGunApiKey, mailGunDomainName, defaultFromAddress), container);

            var netSmtpDispatcherService = container.Options.DefaultLifestyle.CreateRegistration <ISystemNetSmtpEmailDispatcherService>(
                () => new SystemNetSmtpEmailDispatcherService(defaultFromAddress), container);

            container.RegisterConditional(typeof(IEmailDispatcherService), mailGunDispatcherService, context => "mailgun".Equals(activeEmailDispatcherService));
            container.RegisterConditional(typeof(IEmailDispatcherService), netSmtpDispatcherService, context => !context.Handled);             // Default

            //
            container.RegisterSingleton(() => new BlobServiceConfigs()
            {
                DefaultThumbBackgroundHexColor = AppSettings.Blobs.DefaultThumbBackgroundHexColor,
                DefaultThumbForegroundHexColor = AppSettings.Blobs.DefaultThumbForegroundHexColor
            });

            container.Register <IBlobService, BlobService>();
            container.Register <IGlobalizationService, GlobalizationService>();
            container.Register <IRealtimeService, RealtimeService>();

            //
            container.Register(typeof(IValidator <>), domainAssemblies);
            container.Register <ISessionContext>(() =>
            {
                if (AdvancedExtensions.IsVerifying(container) || HttpContext.Current == null)
                {
                    return(UserSessionContext.Null);
                }

                var currentPrincipal = new AppPrincipal(HttpContext.Current.User);

                return(new UserSessionContext(
                           userId: currentPrincipal.Id
                           ));
            });

            //
            container.Register <IPasswordHasher, PasswordHasher>();

            //
            container.RegisterSingleton <ILogger>(() =>
            {
                var logger = new LoggerConfiguration();

                var loggerFilePath = Path.Combine(
                    AppDomain.CurrentDomain.BaseDirectory,
                    AppSettings.Logger.StorageFolder.Trim('~').Trim('\\', '/').Replace("/", "\\"),
                    "log_.txt"
                    );

                logger = logger.Enrich.With <SerilogActivityIdEnricher>();

                logger = logger.WriteTo.Async((log) => log.File(
                                                  new SerilogTextFormatter(),
                                                  loggerFilePath,
                                                  rollingInterval: RollingInterval.Day,
                                                  shared: true
                                                  ));

                logger = logger.WriteTo.Async((log) => log.MSSqlServer(
                                                  connectionString,
                                                  tableName: "Logs",
                                                  autoCreateSqlTable: true
                                                  ));

                return(logger.CreateLogger());
            });

            //
            container.Register <DatabusHub>();

            //
            container.Verify();

            return(container);
        }
        private void SetupApplicationRuntime(IAppBuilder appBuilder, Container container)
        {
            //
            appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                CookieName         = AppSettings.Auth.CookieName,
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath          = new PathString(AppSettings.Auth.LogInPath),

                Provider = new CookieAuthenticationProvider
                {
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity <AppUserManager, AppUserEntity, int>(
                        validateInterval: TimeSpan.FromMinutes(0),
                        regenerateIdentityCallback: (manager, user) =>
                    {
                        var currentPricipal       = HttpContext.Current.User;
                        var currentAdminPrincipal = new AppPrincipal(currentPricipal);

                        var currentIsPersistentState = currentAdminPrincipal.IsPersistent;
                        var currentScreenLockState   = currentAdminPrincipal.ScreenLocked;

                        return(user.GenerateUserIdentityAsync(
                                   manager,
                                   isPersistentState: currentIsPersistentState,
                                   screenLockedState: currentScreenLockState
                                   ));
                    },
                        getUserIdCallback: (user) =>
                    {
                        return(user.GetUserId <int>());
                    }
                        )
                }
            });

            //
            var imageResizerBlobsInfraPlugin = new ImageResizerThumbPlugin(
                blobService: container.GetInstance <IBlobStorageService>()
                );

            imageResizerBlobsInfraPlugin.Install(ImageResizer.Configuration.Config.Current);

            //
            ValidatorOptions.LanguageManager = new ValidationLanguageManager();

            FluentValidationModelValidatorProvider.Configure(config =>
            {
                config.ValidatorFactory = new SimpleInjectorValidatorFactory(container);
            });

            //
            DependencyResolver.SetResolver(
                new SimpleInjectorDependencyResolver(container)
                );

            //
            var serializer = JsonSerializer.Create(new SharedJsonSettings()
            {
                ContractResolver = new SignalRCamelCaseJsonResolver()
            });

            //
            GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);
            GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new UserIdProvider());
            GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => new HubsActivator());

            //
            appBuilder.MapSignalR();
        }