public IAsyncResult BeginAuthenticateAsClient(string targetHost, AsyncCallback asyncCallback, Object asyncState)
        {
            var waitCallback = new WaitCallback(StartAuthentication);

            var result = new AuthenticateResult();
            result.Callback = asyncCallback;
            result.AsyncState = asyncState;

            ThreadPool.QueueUserWorkItem(waitCallback, result);
            return result;
        }
        public static void RaiseLocalLoginSuccessEvent(this IEventService events, IDictionary<string, object> env, string username, SignInMessage signInMessage, AuthenticateResult authResult)
        {
            if (events == null) throw new ArgumentNullException("events");

            var evt = new LocalAuthenticationEvent()
            {
                Id = EventConstants.Ids.SuccessfulLocalLogin,
                EventType = EventType.Success,
                Message = Resources.Events.LocalLoginSuccess,
                SubjectId = authResult.User.GetSubjectId(),
                SignInMessage = signInMessage,
                LoginUserName = username
            };
            evt.ApplyEnvironment(env);
            events.Raise(evt);
        }
 public override Task<AuthenticateResult> PreAuthenticateAsync(SignInMessage message)
 {
     var idp = context.Request.Cookies["idp"];
     if (String.IsNullOrWhiteSpace(idp))
     {
         // no idp, so redirect
         var url = new Claim("url", context.Request.Uri.AbsoluteUri);
         var result = new AuthenticateResult("~/hrd", "hrd", "hrd", new Claim[] { url });
         return Task.FromResult(result);
     }
     else
     {
         // we have idp, so set it
         context.Response.Cookies.Append("idp", ".", new CookieOptions { Expires = DateTime.UtcNow.AddYears(-1) });
         message.IdP = idp;
         return Task.FromResult<AuthenticateResult>(null);
     }
 }
        public Task<AuthenticateResult> AuthenticateLocalAsync(string username, string password, SignInMessage message = null)
        {
            if (message != null)
            {
                var tenant = message.Tenant;

                if (username == password)
                {
                    var claims = new List<Claim>
                    {
                        new Claim("account_store", tenant)
                    };

                    var result = new AuthenticateResult("123", username, 
                        claims: claims,
                        authenticationMethod: "custom");

                    return Task.FromResult(new AuthenticateResult("123", username, claims));
                }
            }

            // default account store
            throw new NotImplementedException();
        }
        private IHttpActionResult SignInAndRedirect(
            AuthenticateResult authResult,
            string authenticationMethod,
            string identityProvider,
            long authTime = 0)
        {
            SignIn(authResult, authenticationMethod, identityProvider, authTime);

            var redirectUrl = GetRedirectUrl(authResult);
            Logger.InfoFormat("redirecting to: {0}", redirectUrl);
            return Redirect(redirectUrl);
        }
Beispiel #6
0
        private async Task <(ApplicationUser user, string provider, string providerUserId, IEnumerable <Claim> claims)> FindUserFromExternalProviderAsync(AuthenticateResult result)
        {
            var externalUser = result.Principal;

            // try to determine the unique id of the external user (issued by the provider)
            // the most common claim type for that are the sub claim and the NameIdentifier
            // depending on the external provider, some other claim type might be used
            var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??
                              externalUser.FindFirst(ClaimTypes.NameIdentifier) ??
                              throw new Exception("Unknown userid");

            // remove the user id claim so we don't include it as an extra claim if/when we provision the user
            var claims = externalUser.Claims.ToList();

            claims.Remove(userIdClaim);

            var provider       = result.Properties.Items["scheme"];
            var providerUserId = userIdClaim.Value;

            // find external user
            var user = await _userManager.FindByLoginAsync(provider, providerUserId); //_user.FindByExternalProvider(provider, providerUserId);

            return(user, provider, providerUserId, claims);
        }
        private (TestUser user, string provider, string providerUserId, IEnumerable <Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)
        {
            var externalUser = result.Principal;

            // try to determine the unique id of the external user (issued by the provider)
            // the most common claim type for that are the sub claim and the NameIdentifier
            // depending on the external provider, some other claim type might be used
            var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??
                              externalUser.FindFirst(ClaimTypes.NameIdentifier) ??
                              // We also want to check upn as a possible user id before failing
                              externalUser.FindFirst(ClaimTypes.Upn) ??
                              throw new Exception("Unknown userid");

            // Don't remove the user id claim here because we might want to include it in a token
            var claims = externalUser.Claims.ToList();

            var provider       = result.Properties.Items["scheme"];
            var providerUserId = userIdClaim.Value;

            // find external user
            var user = _users.FindByExternalProvider(provider, providerUserId);

            return(user, provider, providerUserId, claims);
        }
        private async Task <AuthenticateResult> HandleLegacyAuthentication(UserSettings userSettings, HttpContext context)
        {
            // **************************************************
            // Authenticate based on SiteMinder Headers
            // **************************************************
            _logger.Debug("Parsing the HTTP headers for SiteMinder authentication credential");
            _logger.Debug("Getting user data from headers");

            FileManagerClient _fileManagerClient = (FileManagerClient)context.RequestServices.GetService(typeof(FileManagerClient));

            if (!string.IsNullOrEmpty(context.Request.Headers[_options.SiteMinderUserDisplayNameKey]))
            {
                userSettings.UserDisplayName = context.Request.Headers[_options.SiteMinderUserDisplayNameKey];
            }

            if (!string.IsNullOrEmpty(context.Request.Headers[_options.SiteMinderBusinessLegalNameKey]))
            {
                userSettings.BusinessLegalName = context.Request.Headers[_options.SiteMinderBusinessLegalNameKey];
            }

            var userId = context.Request.Headers[_options.SiteMinderUserNameKey];

            if (string.IsNullOrEmpty(userId))
            {
                userId = context.Request.Headers[_options.SiteMinderUniversalIdKey];
            }

            string siteMinderGuid         = context.Request.Headers[_options.SiteMinderUserGuidKey];
            string siteMinderBusinessGuid = context.Request.Headers[_options.SiteMinderBusinessGuidKey];
            string siteMinderUserType     = context.Request.Headers[_options.SiteMinderUserTypeKey];


            // **************************************************
            // Validate credentials
            // **************************************************
            if (string.IsNullOrEmpty(userId))
            {
                _logger.Debug(_options.MissingSiteMinderUserIdError);
                return(AuthenticateResult.Fail(_options.MissingSiteMinderGuidError));
            }

            if (string.IsNullOrEmpty(siteMinderGuid))
            {
                _logger.Debug(_options.MissingSiteMinderGuidError);
                return(AuthenticateResult.Fail(_options.MissingSiteMinderGuidError));
            }
            if (string.IsNullOrEmpty(siteMinderUserType))
            {
                _logger.Debug(_options.MissingSiteMinderUserTypeError);
                return(AuthenticateResult.Fail(_options.MissingSiteMinderUserTypeError));
            }

            _logger.Debug("Loading user external id = " + siteMinderGuid);
            // 3/18/2020 - Note that LoadUserLegacy will now work if there is a match on the guid, as well as a match on name in a case where there is no guid.
            userSettings.AuthenticatedUser = await _dynamicsClient.LoadUserLegacy(siteMinderGuid, context.Request.Headers, _ms_logger);

            _logger.Information("After getting authenticated user = "******" (" + userId + ")");
                return(AuthenticateResult.Fail(_options.InactivegDbUserIdError));
            }

            // set the usertype to siteminder
            if (userSettings.AuthenticatedUser != null &&
                !string.IsNullOrEmpty(siteMinderUserType))
            {
                userSettings.AuthenticatedUser.UserType = siteMinderUserType;
            }

            userSettings.UserType = siteMinderUserType;

            // Get the various claims for the current user.
            ClaimsPrincipal userPrincipal = userSettings.AuthenticatedUser.ToClaimsPrincipal(_options.Scheme, userSettings.UserType);

            // **************************************************
            // Create authenticated user
            // **************************************************
            _logger.Debug("Authentication successful: " + userId);
            _logger.Debug("Setting identity and creating session for: " + userId);

            // create session info for the current user
            userSettings.UserId                = userId;
            userSettings.UserAuthenticated     = true;
            userSettings.IsNewUserRegistration = userSettings.AuthenticatedUser == null;

            // set other session info
            userSettings.SiteMinderGuid         = siteMinderGuid;
            userSettings.SiteMinderBusinessGuid = siteMinderBusinessGuid;
            _logger.Debug("Before getting contact and account ids = " + userSettings.GetJson());

            if (userSettings.AuthenticatedUser != null)
            {
                userSettings.ContactId = userSettings.AuthenticatedUser.ContactId.ToString();
                // ensure that the given account has a documents folder.

                if (siteMinderBusinessGuid != null) // BCeID user
                {
                    var contact = _dynamicsClient.GetActiveContactByExternalId(userSettings.ContactId);
                    if (contact == null)
                    {
                        // try by other means.
                        var contactVM = new ViewModels.Contact();
                        contactVM.CopyHeaderValues(context.Request.Headers);
                        contact = _dynamicsClient.GetContactByContactVmBlankSmGuid(contactVM);
                    }
                    if (contact != null && contact.Contactid != null)
                    {
                        await CreateSharePointContactDocumentLocation(_fileManagerClient, contact);
                    }

                    // Note that this will search for active accounts
                    var account = await _dynamicsClient.GetActiveAccountBySiteminderBusinessGuid(siteMinderBusinessGuid);

                    if (account == null)
                    {
                        // try by other means.
                        account = _dynamicsClient.GetActiveAccountByLegalName(userSettings.BusinessLegalName);
                    }
                    if (account != null && account.Accountid != null)
                    {
                        userSettings.AccountId = account.Accountid;
                        userSettings.AuthenticatedUser.AccountId = Guid.Parse(account.Accountid);

                        // ensure that the given account has a documents folder.
                        await CreateSharePointAccountDocumentLocation(_fileManagerClient, account);
                    }
                    else  // force the new user process if contact exists but account does not.
                    {
                        userSettings.AuthenticatedUser     = null;
                        userSettings.IsNewUserRegistration = true;
                    }

                    // handle cases where Contact was deleted.
                    if (contact == null)
                    {
                        userSettings.IsNewUserRegistration = true;
                    }
                }
            }

            // add the worker settings if it is a new user.
            if (userSettings.IsNewUserRegistration)
            {
                userSettings.NewWorker = new Worker();
                userSettings.NewWorker.CopyHeaderValues(context.Request.Headers);

                userSettings.NewContact = new ViewModels.Contact();
                userSettings.NewContact.CopyHeaderValues(context.Request.Headers);
            }
            else if (siteMinderUserType == "VerifiedIndividual")
            {
                await HandleVerifiedIndividualLogin(userSettings, context);

                if (HttpUtility.ParseQueryString(context.Request.QueryString.ToString()).Get("path") != "cannabis-associate-screening")
                {
                    await HandleWorkerLogin(userSettings, context);
                }
            }

            // **************************************************
            // Update user settings
            // **************************************************
            UserSettings.SaveUserSettings(userSettings, context);

            return(AuthenticateResult.Success(new AuthenticationTicket(userPrincipal, null, Options.Scheme)));
        }
        private async Task <AuthenticateResult> LoginDevUser(HttpContext context, IDynamicsClient dynamicsClient)
        {
            string       userId               = null;
            string       devCompanyId         = null;
            bool         isDeveloperLogin     = false;
            bool         isBCSCDeveloperLogin = false;
            UserSettings userSettings         = new UserSettings();

            // check for a fake BCeID login

            string temp = context.Request.Cookies[_options.DevAuthenticationTokenKey];

            if (string.IsNullOrEmpty(temp)) // could be an automated test user.
            {
                temp = context.Request.Headers["DEV-USER"];
            }

            if (!string.IsNullOrEmpty(temp))
            {
                if (temp.Contains("::"))
                {
                    var temp2 = temp.Split("::");
                    userId = temp2[0];
                    if (temp2.Length >= 2)
                    {
                        devCompanyId = temp2[1];
                    }
                    else
                    {
                        devCompanyId = temp2[0];
                    }
                }
                else
                {
                    userId       = temp;
                    devCompanyId = temp;
                }
                isDeveloperLogin = true;

                _logger.Debug("Got user from dev cookie = " + userId + ", company = " + devCompanyId);
            }
            else
            {
                // same set of tests for a BC Services Card dev login
                temp = context.Request.Cookies[_options.DevBCSCAuthenticationTokenKey];

                if (string.IsNullOrEmpty(temp)) // could be an automated test user.
                {
                    temp = context.Request.Headers["DEV-BCSC-USER"];
                }

                if (!string.IsNullOrEmpty(temp))
                {
                    userId = temp;
                    isBCSCDeveloperLogin = true;
                    _logger.Debug("Got user from dev cookie = " + userId);
                }
            }

            if (isDeveloperLogin)
            {
                _logger.Debug("Generating a Development user");
                userSettings.BusinessLegalName      = devCompanyId + " TestBusiness";
                userSettings.UserDisplayName        = userId + " TestUser";
                userSettings.SiteMinderGuid         = GuidUtility.CreateIdForDynamics("contact", userSettings.UserDisplayName).ToString();
                userSettings.SiteMinderBusinessGuid = GuidUtility.CreateIdForDynamics("account", userSettings.BusinessLegalName).ToString();
                userSettings.UserType = "Business";
            }
            else if (isBCSCDeveloperLogin)
            {
                _logger.Debug("Generating a Development BC Services user");
                userSettings.BusinessLegalName      = null;
                userSettings.UserDisplayName        = userId + " Associate";
                userSettings.SiteMinderGuid         = GuidUtility.CreateIdForDynamics("bcsc", userSettings.UserDisplayName).ToString();
                userSettings.SiteMinderBusinessGuid = null;
                userSettings.UserType = "VerifiedIndividual";
            }

            NameValueCollection queryStringParams = HttpUtility.ParseQueryString(context.Request.QueryString.ToString());

            if (queryStringParams.Get("path") == "cannabis-associate-screening" && queryStringParams.Get("success") == "false")
            {
                context.Request.Headers.Add("smgov_givenname", "NORMAN");
                context.Request.Headers.Add("smgov_givennames", "Norman Percevel ");
                context.Request.Headers.Add("smgov_useremail", "*****@*****.**");
                context.Request.Headers.Add("smgov_birthdate", "1986-12-03");
                context.Request.Headers.Add("smgov_sex", "Male");
                context.Request.Headers.Add("smgov_streetaddress", "2000 STORMAN ROW");
                context.Request.Headers.Add("smgov_city", "PENTICTON");
                context.Request.Headers.Add("smgov_postalcode", "V8V8V8");
                context.Request.Headers.Add("smgov_province", "BC");
                context.Request.Headers.Add("smgov_country", "CA");
                context.Request.Headers.Add("smgov_surname", "ROCKWELL");
                userSettings.UserDisplayName = "NORMAN ROCKWELL";
            }
            else if (queryStringParams.Get("path") == "cannabis-associate-screening")
            {
                context.Request.Headers.Add("smgov_givenname", "JOE");
                context.Request.Headers.Add("smgov_givennames", "Joe Shmoe ");
                context.Request.Headers.Add("smgov_useremail", "*****@*****.**");
                context.Request.Headers.Add("smgov_birthdate", "1986-12-03");
                context.Request.Headers.Add("smgov_sex", "Male");
                context.Request.Headers.Add("smgov_streetaddress", "2000 COLONIAL ROW");
                context.Request.Headers.Add("smgov_city", "PENTICTON");
                context.Request.Headers.Add("smgov_postalcode", "V2A7P4");
                context.Request.Headers.Add("smgov_province", "BC");
                context.Request.Headers.Add("smgov_country", "CA");
                context.Request.Headers.Add("smgov_surname", "ONE");
                userSettings.UserDisplayName = "JOE ONE";
                userSettings.ContactId       = "3c254b30-ebf2-ea11-b81d-00505683fbf4";
            }

            _logger.Debug("DEV MODE Setting identity and creating session for: " + userId);

            // create session info for the current user
            userSettings.AuthenticatedUser = await _dynamicsClient.LoadUserLegacy(userSettings.SiteMinderGuid, context.Request.Headers, _ms_logger);

            if (userSettings.AuthenticatedUser == null)
            {
                userSettings.UserAuthenticated     = true;
                userSettings.IsNewUserRegistration = true;
            }
            else
            {
                userSettings.AuthenticatedUser.UserType = userSettings.UserType;
                userSettings.AccountId             = userSettings.AuthenticatedUser.AccountId.ToString();
                userSettings.ContactId             = userSettings.AuthenticatedUser.ContactId.ToString();
                userSettings.UserAuthenticated     = true;
                userSettings.IsNewUserRegistration = false;
            }
            userSettings.UserId = userId;

            ClaimsPrincipal userPrincipal = userSettings.AuthenticatedUser.ToClaimsPrincipal(_options.Scheme, userSettings.UserType);

            UserSettings.SaveUserSettings(userSettings, context);
            return(AuthenticateResult.Success(new AuthenticationTicket(userPrincipal, null, _options.Scheme)));
        }
        public async Task<IHttpActionResult> ResumeLoginFromRedirect(string resume)
        {
            Logger.Info("Callback requested to resume login from partial login");

            if (resume.IsMissing())
            {
                Logger.Error("no resumeId passed");
                return RenderErrorPage();
            }

            var user = await context.GetIdentityFromPartialSignIn();
            if (user == null)
            {
                Logger.Error("no identity from partial login");
                return RenderErrorPage();
            }

            var type = GetClaimTypeForResumeId(resume);
            var resumeClaim = user.FindFirst(type);
            if (resumeClaim == null)
            {
                Logger.Error("no claim matching resumeId");
                return RenderErrorPage();
            }

            var signInId = resumeClaim.Value;
            if (signInId.IsMissing())
            {
                Logger.Error("No signin id found in resume claim");
                return RenderErrorPage();
            }

            var signInMessage = signInMessageCookie.Read(signInId);
            if (signInMessage == null)
            {
                Logger.Error("No cookie matching signin id found");
                return RenderErrorPage(localizationService.GetMessage(MessageIds.NoSignInCookie));
            }

            // check to see if the partial login has all the claim types needed to login
            AuthenticateResult result = null;
            if (Constants.AuthenticateResultClaimTypes.All(claimType => user.HasClaim(claimType)))
            {
                Logger.Info("Authentication claims found -- logging user in");
                
                // the user/subject was known, so pass thru (without the redirect claims)
                if (user.HasClaim(Constants.ClaimTypes.PartialLoginReturnUrl))
                {
                    user.RemoveClaim(user.FindFirst(Constants.ClaimTypes.PartialLoginReturnUrl));
                }
                if (user.HasClaim(Constants.ClaimTypes.ExternalProviderUserId))
                {
                    user.RemoveClaim(user.FindFirst(Constants.ClaimTypes.ExternalProviderUserId));
                }
                if (user.HasClaim(GetClaimTypeForResumeId(resume)))
                {
                    user.RemoveClaim(user.FindFirst(GetClaimTypeForResumeId(resume)));
                }
                
                result = new AuthenticateResult(new ClaimsPrincipal(user));

                eventService.RaisePartialLoginCompleteEvent(user, signInId, signInMessage);
            }
            else
            {
                Logger.Info("Authentication claims not found -- looking for ExternalProviderUserId to call AuthenticateExternalAsync");
                
                // the user was not known, we need to re-execute AuthenticateExternalAsync
                // to obtain a subject to proceed
                var externalProviderClaim = user.FindFirst(Constants.ClaimTypes.ExternalProviderUserId);
                if (externalProviderClaim == null)
                {
                    Logger.Error("No ExternalProviderUserId claim found -- rendering error page");
                    return RenderErrorPage();
                }

                var provider = externalProviderClaim.Issuer;
                var providerId = externalProviderClaim.Value;
                var externalId = new ExternalIdentity
                {
                    Provider = provider,
                    ProviderId = providerId,
                    Claims = user.Claims
                };

                result = await userService.AuthenticateExternalAsync(externalId, signInMessage);

                if (result == null)
                {
                    Logger.Warn("user service failed to authenticate external identity");
                    
                    var msg = localizationService.GetMessage(MessageIds.NoMatchingExternalAccount);
                    eventService.RaiseExternalLoginFailureEvent(externalId, signInId, signInMessage, msg);
                    
                    return await RenderLoginPage(signInMessage, signInId, msg);
                }

                if (result.IsError)
                {
                    Logger.WarnFormat("user service returned error message: {0}", result.ErrorMessage);

                    eventService.RaiseExternalLoginFailureEvent(externalId, signInId, signInMessage, result.ErrorMessage);
                    
                    return await RenderLoginPage(signInMessage, signInId, result.ErrorMessage);
                }

                eventService.RaiseExternalLoginSuccessEvent(externalId, signInId, signInMessage, result);
            }

            return SignInAndRedirect(signInMessage, signInId, result);
        }
Beispiel #11
0
        protected override async Task <AuthenticateResult> HandleRemoteAuthenticateAsync()
        {
            AuthenticationProperties properties = null;
            var query = Request.Query;

            var error = query["error"];

            if (!StringValues.IsNullOrEmpty(error))
            {
                var failureMessage = new StringBuilder();
                failureMessage.Append(error);
                var errorDescription = query["error_description"];
                if (!StringValues.IsNullOrEmpty(errorDescription))
                {
                    failureMessage.Append(";Description=").Append(errorDescription);
                }
                var errorUri = query["error_uri"];
                if (!StringValues.IsNullOrEmpty(errorUri))
                {
                    failureMessage.Append(";Uri=").Append(errorUri);
                }

                return(AuthenticateResult.Fail(failureMessage.ToString()));
            }

            var code  = query["code"];
            var state = query["state"];

            properties = Options.StateDataFormat.Unprotect(state);
            if (properties == null)
            {
                return(AuthenticateResult.Fail("The oauth state was missing or invalid."));
            }

            // OAuth2 10.12 CSRF
            if (!ValidateCorrelationId(properties))
            {
                return(AuthenticateResult.Fail("Correlation failed."));
            }

            if (StringValues.IsNullOrEmpty(code))
            {
                return(AuthenticateResult.Fail("Code was not found."));
            }

            var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath));

            if (tokens.Error != null)
            {
                return(AuthenticateResult.Fail(tokens.Error));
            }

            if (string.IsNullOrEmpty(tokens.AccessToken))
            {
                return(AuthenticateResult.Fail("Failed to retrieve access token."));
            }

            var identity = new ClaimsIdentity(Options.ClaimsIssuer);

            if (Options.SaveTokens)
            {
                var authTokens = new List <AuthenticationToken>();

                authTokens.Add(new AuthenticationToken {
                    Name = "access_token", Value = tokens.AccessToken
                });
                if (!string.IsNullOrEmpty(tokens.RefreshToken))
                {
                    authTokens.Add(new AuthenticationToken {
                        Name = "refresh_token", Value = tokens.RefreshToken
                    });
                }

                if (!string.IsNullOrEmpty(tokens.TokenType))
                {
                    authTokens.Add(new AuthenticationToken {
                        Name = "token_type", Value = tokens.TokenType
                    });
                }

                if (!string.IsNullOrEmpty(tokens.ExpiresIn))
                {
                    int value;
                    if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
                    {
                        // https://www.w3.org/TR/xmlschema-2/#dateTime
                        // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
                        var expiresAt = Options.SystemClock.UtcNow + TimeSpan.FromSeconds(value);
                        authTokens.Add(new AuthenticationToken
                        {
                            Name  = "expires_at",
                            Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
                        });
                    }
                }

                properties.StoreTokens(authTokens);
            }

            return(AuthenticateResult.Success(await CreateTicketAsync(identity, properties, tokens)));
        }
 public void ProcessLoginCallbackForWsFed(AuthenticateResult externalResult, List <Claim> localClaims, AuthenticationProperties localSignInProps)
 {
 }
        public async Task <IdentityUser> TryConnectExternalLoginToExistingUser(string providerUserId, AuthenticateResult result)
        {
            var user = await FindUser(result);

            if (user != null)
            {
                // mark email as confirmed -- this is saved with the operation below
                user.EmailConfirmed = true;
                await TryConnectExternalLoginToUser(user, providerUserId, result);

                return(user);
            }

            return(null);
        }
Beispiel #14
0
        /// <summary>
        /// Searches the 'Authorization' header for a 'Bearer' token.
        /// </summary>
        /// <returns></returns>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            string token = null;

            try
            {
                // Give application opportunity to find from a different location, adjust, or reject token
                var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options);

                // event can set the token
                await Events.MessageReceived(messageReceivedContext);

                if (messageReceivedContext.Result != null)
                {
                    return(messageReceivedContext.Result);
                }

                // If application retrieved token from somewhere else, use that.
                token = messageReceivedContext.Token;

                if (string.IsNullOrEmpty(token))
                {
                    string authorization = Request.Headers["Authorization"];

                    // If no authorization header found, nothing to process further
                    if (string.IsNullOrEmpty(authorization))
                    {
                        return(AuthenticateResult.NoResult());
                    }

                    if (authorization.StartsWith("FakeBearer ", StringComparison.OrdinalIgnoreCase))
                    {
                        token = authorization.Substring("FakeBearer ".Length).Trim();
                    }

                    // If no token found, no further work possible
                    if (string.IsNullOrEmpty(token))
                    {
                        return(AuthenticateResult.NoResult());
                    }
                }

                Dictionary <string, dynamic> tokenDecoded = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(token);

                ClaimsIdentity id = new ClaimsIdentity("Identity.Application", "name", "role");

                foreach (var td in tokenDecoded)
                {
                    if (td.Key == "sub")
                    {
                        id.AddClaim(new Claim("sub", td.Value.ToString()));
                        if (!tokenDecoded.Any(c => c.Key == "name"))
                        {
                            id.AddClaim(new Claim("name", td.Value.ToString()));
                        }
                    }
                    else
                    {
                        if (td.Value is string)
                        {
                            id.AddClaim(new Claim(td.Key, td.Value));
                        }
                        else if (td.Value is IEnumerable)
                        {
                            foreach (string subValue in td.Value)
                            {
                                id.AddClaim(new Claim(td.Key, subValue));
                            }
                        }
                        else
                        {
                            throw new Exception("Unknown type");
                        }
                    }
                }

                ClaimsPrincipal principal = new ClaimsPrincipal(id);

                var tokenValidatedContext = new TokenValidatedContext(Context, Scheme, Options)
                {
                    Principal = principal
                };

                await Events.TokenValidated(tokenValidatedContext);

                if (tokenValidatedContext.Result != null)
                {
                    return(tokenValidatedContext.Result);
                }

                if (Options.SaveToken)
                {
                    tokenValidatedContext.Properties.StoreTokens(new[]
                    {
                        new AuthenticationToken {
                            Name = "access_token", Value = token
                        }
                    });
                }

                tokenValidatedContext.Success();
                return(tokenValidatedContext.Result);
            }
            catch (Exception ex)
            {
                var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
                {
                    Exception = ex
                };

                await Events.AuthenticationFailed(authenticationFailedContext);

                if (authenticationFailedContext.Result != null)
                {
                    return(authenticationFailedContext.Result);
                }

                throw;
            }
        }
Beispiel #15
0
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            if (!Request.Cookies.ContainsKey(AccessToken) || !Request.Cookies.ContainsKey(User_Id))
            {
                Log.Error("No Access Token or User Id found.");
                return(await Task.FromResult(AuthenticateResult.NoResult()));
            }

            if (!AuthenticationHeaderValue.TryParse($"{"Bearer " + Request.Cookies[AccessToken]}", out AuthenticationHeaderValue headerValue))
            {
                Log.Error("Could not pass token from authentication Header");
                return(await Task.FromResult(AuthenticateResult.NoResult()));
            }

            if (!AuthenticationHeaderValue.TryParse($"{"Bearer " + Request.Cookies[User_Id]}", out AuthenticationHeaderValue headerValueId))
            {
                Log.Error("Could not Parse User Id from authentication Header");
                return(await Task.FromResult(AuthenticateResult.NoResult()));
            }

            try
            {
                var key     = Encoding.ASCII.GetBytes(_appSettings.Secret);
                var handler = new JwtSecurityTokenHandler();

                TokenValidationParameters validationParameters = new TokenValidationParameters
                {
                    ValidateIssuer           = true,
                    ValidateIssuerSigningKey = true,
                    ValidateAudience         = true,
                    ValidIssuer      = _appSettings.Site,
                    ValidAudience    = _appSettings.Audience,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateLifetime = true,
                    ClockSkew        = TimeSpan.Zero
                };

                var protectorProvider = _provider.GetService <IDataProtectionProvider>();
                var protector         = protectorProvider.CreateProtector(_dataProtectionKeys.ApplicationUserKey);

                var decryptedUid   = protector.Unprotect(headerValueId.Parameter);
                var decryptedToken = protector.Unprotect(headerValue.Parameter);

                TokenModel tokenModel = new TokenModel();

                using (var scope = _provider.CreateScope())
                {
                    var dbContextService = scope.ServiceProvider.GetService <ApplicationDbContext>();
                    var userToken        = dbContextService.Tokens.Include(x => x.User)
                                           .FirstOrDefault(ut => ut.UserId == decryptedUid && ut.User.UserName == Request.Cookies[Username] &&
                                                           ut.User.Id == decryptedUid && ut.User.UserRole == "Administrator");

                    tokenModel = userToken;
                }

                if (tokenModel == null)
                {
                    return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this page.")));
                }

                IDataProtector layerTwoProtector      = protectorProvider.CreateProtector(tokenModel?.EncryptionKeyJwt);
                string         decryptedTokenLayerTwo = layerTwoProtector.Unprotect(decryptedToken);

                var validateToken = handler.ValidateToken(decryptedTokenLayerTwo, validationParameters, out var securityToken);

                if (!(securityToken is JwtSecurityToken jwtSecurityToken) || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
                {
                    return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this page.")));
                }

                var username = validateToken.Claims.FirstOrDefault(claim => claim.Type == ClaimTypes.NameIdentifier)?.Value;

                if (Request.Cookies[Username] != username)
                {
                    return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this page.")));
                }

                var user = await _userManager.FindByNameAsync(username);

                if (user == null)
                {
                    return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this page.")));
                }

                if (!UserRoles.Contains(user.UserRole))
                {
                    return(await Task.FromResult(AuthenticateResult.Fail("You are not authorized to View this page.")));
                }

                var identity  = new ClaimsIdentity(validateToken.Claims, Scheme.Name);
                var principal = new ClaimsPrincipal(identity);
                var ticket    = new AuthenticationTicket(principal, Scheme.Name);
                return(await Task.FromResult(AuthenticateResult.Success(ticket)));
            }
            catch (Exception e)
            {
                Log.Error("An Error Occured while seeding database {Error} {StackTrace} {InnerException} {Source}", e.Message, e.StackTrace, e.Source);
                return(await Task.FromResult(AuthenticateResult.Fail("You are not Authorized")));
            }
        }
Beispiel #16
0
 private static string GetScheme(AuthenticateResult externalLogin)
 {
     return(externalLogin.Properties.Items["scheme"]);
 }
        /// <summary>
        /// 在 "授权" 标头中搜索 "持票人" 令牌。如果找到 "持票人" 令牌, 则使用 <see cref="TokenValidationParameters"/> 在选项设置.
        /// </summary>
        /// <returns></returns>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            string token = null;

            try {
                // 提供从不同位置查找、调整或拒绝令牌的应用程序机会
                var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options);
                // 事件可以设置令牌
                await Events.MessageReceived(messageReceivedContext);

                if (messageReceivedContext.Result != null)
                {
                    return(messageReceivedContext.Result);
                }
                // 如果应用程序从别处检索到标记, 请使用.
                token = messageReceivedContext.Token;

                if (string.IsNullOrEmpty(token))
                {
                    string authorization = Request.Headers["Authorization"];
                    // 如果未找到授权标头, 则无法进一步处理
                    if (string.IsNullOrEmpty(authorization))
                    {
                        return(AuthenticateResult.NoResult());
                    }
                    if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
                    {
                        token = authorization.Substring("Bearer ".Length).Trim();
                    }
                    // 如果找不到任何令牌, 则无法进一步工作
                    if (string.IsNullOrEmpty(token))
                    {
                        return(AuthenticateResult.NoResult());
                    }
                }

                if (_configuration == null && Options.ConfigurationManager != null)
                {
                    _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted);
                }

                var validationParameters = Options.TokenValidationParameters.Clone();
                if (_configuration != null)
                {
                    var issuers = new[] { _configuration.Issuer };
                    validationParameters.ValidIssuers      = validationParameters.ValidIssuers?.Concat(issuers) ?? issuers;
                    validationParameters.IssuerSigningKeys = validationParameters.IssuerSigningKeys?.Concat(_configuration.SigningKeys)
                                                             ?? _configuration.SigningKeys;
                }

                List <Exception> validationFailures = null;
                SecurityToken    validatedToken;
                foreach (var validator in Options.SecurityTokenValidators)
                {
                    if (validator.CanReadToken(token))
                    {
                        ClaimsPrincipal principal;
                        try {
                            principal = validator.ValidateToken(token, validationParameters, out validatedToken);

                            var validJwt = validatedToken as JwtSecurityToken;

                            if (validJwt == null)
                            {
                                throw new ArgumentException("Invalid JWT");
                            }
                            var uuid = validJwt.Claims.FirstOrDefault(i => i.Type == TokenClaimsKey.UUID);
                            if (uuid != null)
                            {
                                this.Context.SetStringEntry(TokenClaimsKey.UUID, uuid.Value);
                            }
                            var uname = validJwt.Claims.FirstOrDefault(i => i.Type == TokenClaimsKey.UserName);
                            if (uname != null)
                            {
                                this.Context.SetStringEntry(TokenClaimsKey.UserName, uname.Value);
                            }
                            var role = validJwt.Claims.FirstOrDefault(i => i.Type == TokenClaimsKey.RoleID);
                            if (role != null)
                            {
                                this.Context.SetStringEntry(TokenClaimsKey.RoleID, role.Value);
                            }
                            var avatar = validJwt.Claims.FirstOrDefault(i => i.Type == TokenClaimsKey.Avatar);
                            if (avatar != null)
                            {
                                this.Context.SetStringEntry(TokenClaimsKey.Avatar, avatar.Value);
                            }
                        } catch (ArgumentException ex) {
                            if (validationFailures == null)
                            {
                                validationFailures = new List <Exception>(1);
                            }
                            validationFailures.Add(ex);
                            continue;
                        } catch (Exception ex) {
                            //Logger.TokenValidationFailed(token, ex);
                            //为可能由键翻转引起的异常刷新配置。用户还可以请求在事件中进行刷新。
                            if (Options.RefreshOnIssuerKeyNotFound && Options.ConfigurationManager != null &&
                                ex is SecurityTokenSignatureKeyNotFoundException)
                            {
                                Options.ConfigurationManager.RequestRefresh();
                            }
                            if (validationFailures == null)
                            {
                                validationFailures = new List <Exception>(1);
                            }
                            validationFailures.Add(ex);
                            continue;
                        }

                        //Logger.TokenValidationSucceeded();
                        var tokenValidatedContext = new TokenValidatedContext(Context, Scheme, Options)
                        {
                            Principal     = principal,
                            SecurityToken = validatedToken
                        };
                        await Events.TokenValidated(tokenValidatedContext);

                        if (tokenValidatedContext.Result != null)
                        {
                            return(tokenValidatedContext.Result);
                        }
                        if (Options.SaveToken)
                        {
                            tokenValidatedContext.Properties.StoreTokens(new[] {
                                new AuthenticationToken {
                                    Name = "access_token", Value = token
                                }
                            });
                        }
                        tokenValidatedContext.Success();
                        return(tokenValidatedContext.Result);
                    }
                }

                if (validationFailures != null)
                {
                    var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
                    {
                        Exception = (validationFailures.Count == 1) ? validationFailures[0] : new AggregateException(validationFailures)
                    };
                    await Events.AuthenticationFailed(authenticationFailedContext);

                    if (authenticationFailedContext.Result != null)
                    {
                        return(authenticationFailedContext.Result);
                    }
                    return(AuthenticateResult.Fail(authenticationFailedContext.Exception));
                }
                return(AuthenticateResult.Fail("No SecurityTokenValidator available for token: " + token ?? "[null]"));
            } catch (Exception ex) {
                //Logger.ErrorProcessingMessage(ex);
                var authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
                {
                    Exception = ex
                };
                await Events.AuthenticationFailed(authenticationFailedContext);

                if (authenticationFailedContext.Result != null)
                {
                    return(authenticationFailedContext.Result);
                }
                throw;
            }
        }
Beispiel #18
0
    public async Task VerifyAccountControllerExternalLoginWithTokensFlow()
    {
        // Setup the external cookie like it would look from a real OAuth2
        var externalId = "<externalId>";
        var authScheme = "<authScheme>";
        var externalIdentity = new ClaimsIdentity();
        externalIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, externalId));
        var externalPrincipal = new ClaimsPrincipal(externalIdentity);
        var externalLogin = new ExternalLoginInfo(externalPrincipal, authScheme, externalId, "displayname")
        {
            AuthenticationTokens = new[] {
                    new AuthenticationToken { Name = "refresh_token", Value = "refresh" },
                    new AuthenticationToken { Name = "access_token", Value = "access" }
                }
        };

        var context = new DefaultHttpContext();
        var auth = MockAuth(context);
        auth.Setup(a => a.AuthenticateAsync(context, It.IsAny<string>())).Returns(Task.FromResult(AuthenticateResult.NoResult()));
        var contextAccessor = new Mock<IHttpContextAccessor>();
        contextAccessor.Setup(a => a.HttpContext).Returns(context);
        var services = new ServiceCollection()
            .AddSingleton<IConfiguration>(new ConfigurationBuilder().Build())
            .AddLogging()
            .AddSingleton(contextAccessor.Object);
        services.AddIdentity<PocoUser, PocoRole>();
        services.AddSingleton<IUserStore<PocoUser>, InMemoryStore<PocoUser, PocoRole>>();
        services.AddSingleton<IRoleStore<PocoRole>, InMemoryStore<PocoUser, PocoRole>>();

        var app = new ApplicationBuilder(services.BuildServiceProvider());

        // Act
        var user = new PocoUser
        {
            UserName = "******"
        };
        var userManager = app.ApplicationServices.GetRequiredService<UserManager<PocoUser>>();
        var signInManager = app.ApplicationServices.GetRequiredService<SignInManager<PocoUser>>();

        IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user));
        IdentityResultAssert.IsSuccess(await userManager.AddLoginAsync(user, new UserLoginInfo(authScheme, externalId, "whatever")));
        IdentityResultAssert.IsSuccess(await signInManager.UpdateExternalAuthenticationTokensAsync(externalLogin));
        Assert.Equal("refresh", await userManager.GetAuthenticationTokenAsync(user, authScheme, "refresh_token"));
        Assert.Equal("access", await userManager.GetAuthenticationTokenAsync(user, authScheme, "access_token"));
    }
        private Uri GetRedirectUrl(AuthenticateResult authResult)
        {
            if (authResult == null) throw new ArgumentNullException("authResult");

            if (authResult.IsPartialSignIn)
            {
                return new Uri(Request.RequestUri, authResult.PartialSignInRedirectPath.Value);
            }
            else
            {
                var signInMessage = LoadSignInMessage(); 
                return new Uri(signInMessage.ReturnUrl);
            }
        }
        public async Task TryConnectExternalLoginToUser(IdentityUser user, string providerUserId, AuthenticateResult result)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var email               = result.Principal.Claims.FindEmail();
            var provider            = result.Properties.Items["scheme"];
            var providerDisplayName = await _authenticationSchemeProvider.GetProviderDisplayName(provider);

            var identityResult = await _userManager.AddLoginAsync(user, new UserLoginInfo(provider, providerUserId, providerDisplayName), email);

            if (!identityResult.Succeeded)
            {
                throw new Exception(identityResult.Errors.First().Description);
            }
        }
        public static async Task RaiseLocalLoginSuccessEventAsync(this IEventService events,
                                                                  string username, string signInMessageId, SignInMessage signInMessage, AuthenticateResult authResult)
        {
            var evt = new Event <LocalLoginDetails>(
                EventConstants.Categories.Authentication,
                Resources.Events.LocalLoginSuccess,
                EventTypes.Success,
                EventConstants.Ids.LocalLoginSuccess,
                new LocalLoginDetails
            {
                SubjectId     = authResult.HasSubject ? authResult.User.GetSubjectId() : null,
                Name          = authResult.User.Identity.Name,
                SignInId      = signInMessageId,
                SignInMessage = signInMessage,
                PartialLogin  = authResult.IsPartialSignIn,
                LoginUserName = username
            });

            await events.RaiseEventAsync(evt);
        }
Beispiel #22
0
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            var request = Context.GetOpenIdConnectRequest();

            if (request == null)
            {
                throw new InvalidOperationException("An identity cannot be extracted from this request.");
            }

            if (request.IsAuthorizationRequest() || request.IsLogoutRequest())
            {
                if (string.IsNullOrEmpty(request.IdTokenHint))
                {
                    return(AuthenticateResult.NoResult());
                }

                var ticket = await DeserializeIdentityTokenAsync(request.IdTokenHint, request);

                if (ticket == null)
                {
                    Logger.LogWarning("The identity token extracted from the 'id_token_hint' " +
                                      "parameter was invalid or malformed and was ignored.");

                    return(AuthenticateResult.NoResult());
                }

                // Tickets are returned even if they
                // are considered invalid (e.g expired).
                return(AuthenticateResult.Success(ticket));
            }

            else if (request.IsTokenRequest())
            {
                // Note: this method can be called from the ApplyTokenResponse event,
                // which may be invoked for a missing authorization code/refresh token.
                if (request.IsAuthorizationCodeGrantType())
                {
                    if (string.IsNullOrEmpty(request.Code))
                    {
                        return(AuthenticateResult.NoResult());
                    }

                    var ticket = await DeserializeAuthorizationCodeAsync(request.Code, request);

                    if (ticket == null)
                    {
                        Logger.LogWarning("The authorization code extracted from the " +
                                          "token request was invalid and was ignored.");

                        return(AuthenticateResult.NoResult());
                    }

                    return(AuthenticateResult.Success(ticket));
                }

                else if (request.IsRefreshTokenGrantType())
                {
                    if (string.IsNullOrEmpty(request.RefreshToken))
                    {
                        return(AuthenticateResult.NoResult());
                    }

                    var ticket = await DeserializeRefreshTokenAsync(request.RefreshToken, request);

                    if (ticket == null)
                    {
                        Logger.LogWarning("The refresh token extracted from the " +
                                          "token request was invalid and was ignored.");

                        return(AuthenticateResult.NoResult());
                    }

                    return(AuthenticateResult.Success(ticket));
                }

                return(AuthenticateResult.NoResult());
            }

            throw new InvalidOperationException("An identity cannot be extracted from this request.");
        }
        private void IssueAuthenticationCookie(string signInMessageId, AuthenticateResult authResult, bool? rememberMe = null)
        {
            if (authResult == null) throw new ArgumentNullException("authResult");

            Logger.InfoFormat("issuing cookie{0}", authResult.IsPartialSignIn ? " (partial login)" : "");

            var props = new Microsoft.Owin.Security.AuthenticationProperties();

            var id = authResult.User.Identities.First();
            if (authResult.IsPartialSignIn)
            {
                // add claim so partial redirect can return here to continue login
                // we need a random ID to resume, and this will be the query string
                // to match a claim added. the claim added will be the original 
                // signIn ID. 
                var resumeId = CryptoRandom.CreateUniqueId();

                var resumeLoginUrl = context.GetPartialLoginResumeUrl(resumeId);
                var resumeLoginClaim = new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, resumeLoginUrl);
                id.AddClaim(resumeLoginClaim);
                id.AddClaim(new Claim(GetClaimTypeForResumeId(resumeId), signInMessageId));
            }
            else
            {
                signInMessageCookie.Clear(signInMessageId);
            }

            if (!authResult.IsPartialSignIn)
            {
                // don't issue persistnt cookie if it's a partial signin
                if (rememberMe == true ||
                    (rememberMe != false && this.options.AuthenticationOptions.CookieOptions.IsPersistent))
                {
                    // only issue persistent cookie if user consents (rememberMe == true) or
                    // if server is configured to issue persistent cookies and user has not explicitly
                    // denied the rememberMe (false)
                    // if rememberMe is null, then user was not prompted for rememberMe
                    props.IsPersistent = true;
                    if (rememberMe == true)
                    {
                        var expires = DateTimeHelper.UtcNow.Add(options.AuthenticationOptions.CookieOptions.RememberMeDuration);
                        props.ExpiresUtc = new DateTimeOffset(expires);
                    }
                }
            }

            ClearAuthenticationCookies();
            
            context.Authentication.SignIn(props, id);
        }
Beispiel #24
0
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, DefaultRequirement requirement)
        {
            AuthorizationFilterContext authorizationFilterContext = context.Resource as AuthorizationFilterContext;
            HttpContext httpContext = authorizationFilterContext.HttpContext;
            IAuthenticationHandlerProvider handlers = httpContext.RequestServices.GetRequiredService <IAuthenticationHandlerProvider>();

            foreach (AuthenticationScheme scheme in await _schemes.GetRequestHandlerSchemesAsync())
            {
                IAuthenticationRequestHandler handler = await handlers.GetHandlerAsync(httpContext, scheme.Name) as IAuthenticationRequestHandler;

                if (handler != null && await handler.HandleRequestAsync())
                {
                    context.Fail();
                    return;
                }
            }
            AuthenticationScheme defaultAuthenticate = await _schemes.GetDefaultAuthenticateSchemeAsync();

            if (defaultAuthenticate != null)
            {
                AuthenticateResult result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);

                if (result?.Principal != null)
                {
                    if (long.Parse(result.Principal.Claims.SingleOrDefault(s => s.Type == "exp").Value) < DateTime.Now.ToIntS())
                    {
                        authorizationFilterContext.Result = new JsonResult(new MessageResult
                        {
                            Msg    = ConifgMessage.TIMEOUT,
                            Status = false
                        })
                        {
                            StatusCode = 401
                        };
                    }
                    else
                    {
                        httpContext.User = result.Principal;
                        if (requirement.Validation != null)
                        {
                            AuthResult validMsg = requirement.Validation(httpContext);
                            if (!validMsg.IsValid)
                            {
                                authorizationFilterContext.Result = new JsonResult(new MessageResult
                                {
                                    Msg    = validMsg.Msg,
                                    Status = false
                                })
                                {
                                    StatusCode = 401
                                };
                            }
                        }
                    }
                }
                else
                {
                    authorizationFilterContext.Result = new JsonResult(new MessageResult
                    {
                        Msg    = ConifgMessage.NOTRIGHT,
                        Status = false
                    })
                    {
                        StatusCode = 401
                    };
                }
            }
            else
            {
                context.Fail();
                return;
            }
            context.Succeed(requirement);
        }
        private void IssueAuthenticationCookie(SignInMessage signInMessage, string signInMessageId, AuthenticateResult authResult, bool?rememberMe = null)
        {
            if (signInMessage == null)
            {
                throw new ArgumentNullException("signInId");
            }
            if (authResult == null)
            {
                throw new ArgumentNullException("authResult");
            }

            Logger.InfoFormat("issuing cookie{0}", authResult.IsPartialSignIn ? " (partial login)" : "");

            var props = new Microsoft.Owin.Security.AuthenticationProperties();

            var id = authResult.User.Identities.First();

            if (authResult.IsPartialSignIn)
            {
                // add claim so partial redirect can return here to continue login
                // we need a random ID to resume, and this will be the query string
                // to match a claim added. the claim added will be the original
                // signIn ID.
                var resumeId = Guid.NewGuid().ToString("N");

                var resumeLoginUrl   = Url.Link(Constants.RouteNames.ResumeLoginFromRedirect, new { resume = resumeId });
                var resumeLoginClaim = new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, resumeLoginUrl);
                id.AddClaim(resumeLoginClaim);
                id.AddClaim(new Claim(GetClaimTypeForResumeId(resumeId), signInMessageId));
            }
            else
            {
                ClearSignInCookie(signInMessageId);
            }

            if (!authResult.IsPartialSignIn)
            {
                // don't issue persistnt cookie if it's a partial signin
                if (rememberMe == true ||
                    (rememberMe != false && this._options.AuthenticationOptions.CookieOptions.IsPersistent))
                {
                    // only issue persistent cookie if user consents (rememberMe == true) or
                    // if server is configured to issue persistent cookies and user has not explicitly
                    // denied the rememberMe (false)
                    // if rememberMe is null, then user was not prompted for rememberMe
                    props.IsPersistent = true;
                    if (rememberMe == true)
                    {
                        var expires = DateTime.UtcNow.Add(_options.AuthenticationOptions.CookieOptions.RememberMeDuration);
                        props.ExpiresUtc = new DateTimeOffset(expires);
                    }
                }
            }

            ClearAuthenticationCookies();

            var ctx = Request.GetOwinContext();

            ctx.Authentication.SignIn(props, id);
        }
        /// <summary>
        /// Process Authentication Request
        /// </summary>
        /// <returns></returns>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            ClaimsPrincipal principal = new ClaimsPrincipal();

            /*
             * // get siteminder headers
             * _logger.LogDebug("Parsing the HTTP headers for SiteMinder authentication credential");
             *
             * SiteMinderAuthOptions options = new SiteMinderAuthOptions();
             * bool isDeveloperLogin = false;
             * bool isBCSCDeveloperLogin = false;
             * try
             * {
             *
             *  HttpContext context = Request.HttpContext;
             *
             *  IHostingEnvironment hostingEnv = (IHostingEnvironment)context.RequestServices.GetService(typeof(IHostingEnvironment));
             *
             *  UserSettings userSettings = new UserSettings();
             *
             *  string userId = null;
             *  string devCompanyId = null;
             *  string siteMinderGuid = "";
             *  string siteMinderBusinessGuid = "";
             *  string siteMinderUserType = "";
             *
             *  // **************************************************
             *  // If this is an Error or Authentiation API - Ignore
             *  // **************************************************
             *  string url = context.Request.GetDisplayUrl().ToLower();
             *
             *  if (url.Contains(".js"))
             *  {
             *      return AuthenticateResult.NoResult();
             *  }
             *
             *  // **************************************************
             *  // Check if we have a Dev Environment Cookie
             *  // **************************************************
             *  //if (!hostingEnv.IsProduction())
             *  //{
             *      // check for a fake BCeID login in dev mode
             *      string temp = context.Request.Cookies[options.DevAuthenticationTokenKey];
             *
             *      if (string.IsNullOrEmpty(temp)) // could be an automated test user.
             *      {
             *          temp = context.Request.Headers["DEV-USER"];
             *      }
             *
             *      if (!string.IsNullOrEmpty(temp))
             *      {
             *          if (temp.Contains("::"))
             *          {
             *              var temp2 = temp.Split("::");
             *              userId = temp2[0];
             *              if (temp2.Length >= 2)
             *                  devCompanyId = temp2[1];
             *              else
             *                  devCompanyId = temp2[0];
             *          }
             *          else
             *          {
             *              userId = temp;
             *              devCompanyId = temp;
             *          }
             *          isDeveloperLogin = true;
             *
             *          _logger.LogDebug("Got user from dev cookie = " + userId + ", company = " + devCompanyId);
             *      }
             *      else
             *      {
             *          // same set of tests for a BC Services Card dev login
             *          temp = context.Request.Cookies[options.DevBCSCAuthenticationTokenKey];
             *
             *          if (string.IsNullOrEmpty(temp)) // could be an automated test user.
             *          {
             *              temp = context.Request.Headers["DEV-BCSC-USER"];
             *          }
             *
             *          if (!string.IsNullOrEmpty(temp))
             *          {
             *              userId = temp;
             *              isBCSCDeveloperLogin = true;
             *
             *              _logger.LogDebug("Got user from dev cookie = " + userId);
             *          }
             *      }
             *  //}
             *
             *  // **************************************************
             *  // Check if the user session is already created
             *  // **************************************************
             *  try
             *  {
             *      _logger.LogInformation("Checking user session");
             *      userSettings = UserSettings.ReadUserSettings(context);
             *      _logger.LogDebug("UserSettings found: " + userSettings.GetJson());
             *  }
             *  catch
             *  {
             *      //do nothing
             *      _logger.LogDebug("No UserSettings found");
             *  }
             *
             *  // is user authenticated - if so we're done
             *  if ((userSettings.UserAuthenticated && string.IsNullOrEmpty(userId)) ||
             *      (userSettings.UserAuthenticated && !string.IsNullOrEmpty(userId) &&
             *       !string.IsNullOrEmpty(userSettings.UserId) && userSettings.UserId == userId))
             *  {
             *      _logger.LogDebug("User already authenticated with active session: " + userSettings.UserId);
             *      principal = userSettings.AuthenticatedUser.ToClaimsPrincipal(options.Scheme, userSettings.UserType);
             *      return AuthenticateResult.Success(new AuthenticationTicket(principal, null, Options.Scheme));
             *  }
             *
             *  string smgov_userdisplayname = context.Request.Headers["smgov_userdisplayname"];
             *  if (!string.IsNullOrEmpty(smgov_userdisplayname))
             *  {
             *      userSettings.UserDisplayName = smgov_userdisplayname;
             *  }
             *
             *  string smgov_businesslegalname = context.Request.Headers["smgov_businesslegalname"];
             *  if (!string.IsNullOrEmpty(smgov_businesslegalname))
             *  {
             *      userSettings.BusinessLegalName = smgov_businesslegalname;
             *  }
             *
             *  // **************************************************
             *  // Authenticate based on SiteMinder Headers
             *  // **************************************************
             *  _logger.LogDebug("Parsing the HTTP headers for SiteMinder authentication credential");
             *
             *  // At this point userID would only be set if we are logging in through as a DEV user
             *
             *  if (string.IsNullOrEmpty(userId))
             *  {
             *      _logger.LogDebug("Getting user data from headers");
             *
             *      userId = context.Request.Headers[options.SiteMinderUserNameKey];
             *      if (string.IsNullOrEmpty(userId))
             *      {
             *          userId = context.Request.Headers[options.SiteMinderUniversalIdKey];
             *      }
             *
             *      siteMinderGuid = context.Request.Headers[options.SiteMinderUserGuidKey];
             *      siteMinderBusinessGuid = context.Request.Headers[options.SiteMinderBusinessGuidKey];
             *      siteMinderUserType = context.Request.Headers[options.SiteMinderUserTypeKey];
             *
             *
             *      // **************************************************
             *      // Validate credentials
             *      // **************************************************
             *      if (string.IsNullOrEmpty(userId))
             *      {
             *          _logger.LogDebug(options.MissingSiteMinderUserIdError);
             *          return AuthenticateResult.Fail(options.MissingSiteMinderGuidError);
             *      }
             *
             *      if (string.IsNullOrEmpty(siteMinderGuid))
             *      {
             *          _logger.LogDebug(options.MissingSiteMinderGuidError);
             *          return AuthenticateResult.Fail(options.MissingSiteMinderGuidError);
             *      }
             *      if (string.IsNullOrEmpty(siteMinderUserType))
             *      {
             *          _logger.LogDebug(options.MissingSiteMinderUserTypeError);
             *          return AuthenticateResult.Fail(options.MissingSiteMinderUserTypeError);
             *      }
             *  }
             *  else // DEV user, setup a fake session and SiteMinder headers.
             *  {
             *      if (isDeveloperLogin )
             *      {
             *          _logger.LogError("Generating a Development user");
             *          userSettings.BusinessLegalName = devCompanyId + " BusinessProfileName";
             *          userSettings.UserDisplayName = userId + " BCeIDContactType";
             *
             *          // search for a matching user.
             *          var existingContact = _dynamicsClient.GetContactByName(userId, "BCeIDContactType");
             *
             *          if (existingContact != null)
             *          {
             *              siteMinderGuid = existingContact.Externaluseridentifier;
             *          }
             *          else
             *          {
             *              siteMinderGuid = GuidUtility.CreateIdForDynamics("contact", userSettings.UserDisplayName).ToString();
             *          }
             *
             *          var existingBusiness = await _dynamicsClient.GetAccountByLegalName(userSettings.BusinessLegalName);
             *          if (existingBusiness != null)
             *          {
             *              siteMinderBusinessGuid = existingBusiness.BcgovBceid;
             *          }
             *          {
             *              siteMinderBusinessGuid = GuidUtility.CreateIdForDynamics("account", userSettings.BusinessLegalName).ToString();
             *          }
             *          siteMinderUserType = "Business";
             *      }
             *      else if (isBCSCDeveloperLogin)
             *      {
             *          _logger.LogError("Generating a Development BC Services user");
             *          userSettings.BusinessLegalName = null;
             *          userSettings.UserDisplayName = userId + " Associate";
             *          siteMinderGuid = GuidUtility.CreateIdForDynamics("bcsc", userSettings.UserDisplayName).ToString();
             *          siteMinderBusinessGuid = null;
             *          siteMinderUserType = "VerifiedIndividual";
             *      }
             *  }
             *
             *  // Previously the code would do a database lookup here.  However there is no backing database for the users table now,
             *  // so we just do a Dynamics lookup on the siteMinderGuid.
             *
             *  _logger.LogDebug("Loading user external id = " + siteMinderGuid);
             *  if (_dynamicsClient != null)
             *  {
             *      userSettings.AuthenticatedUser = await _dynamicsClient.LoadUser(siteMinderGuid, context.Request.Headers, _logger);
             *  }
             *
             *  _logger.LogDebug("After getting authenticated user = "******" (" + userId + ")");
             *      return AuthenticateResult.Fail(options.InactivegDbUserIdError);
             *  }
             *
             *  if (userSettings.AuthenticatedUser != null && !String.IsNullOrEmpty(siteMinderUserType))
             *  {
             *      userSettings.AuthenticatedUser.UserType = siteMinderUserType;
             *  }
             *  userSettings.UserType = siteMinderUserType;
             *
             *  // This line gets the various claims for the current user.
             *  ClaimsPrincipal userPrincipal = userSettings.AuthenticatedUser.ToClaimsPrincipal(options.Scheme, userSettings.UserType);
             *
             *  // **************************************************
             *  // Create authenticated user
             *  // **************************************************
             *  _logger.LogDebug("Authentication successful: " + userId);
             *  _logger.LogDebug("Setting identity and creating session for: " + userId);
             *
             *  // create session info for the current user
             *  userSettings.UserId = userId;
             *  userSettings.UserAuthenticated = true;
             *  userSettings.IsNewUserRegistration = (userSettings.AuthenticatedUser == null);
             *
             *  // set other session info
             *  userSettings.SiteMinderGuid = siteMinderGuid;
             *  userSettings.SiteMinderBusinessGuid = siteMinderBusinessGuid;
             *  _logger.LogDebug("Before getting contact and account ids = " + userSettings.GetJson());
             *
             *  if (userSettings.AuthenticatedUser != null)
             *  {
             *      userSettings.ContactId = userSettings.AuthenticatedUser.ContactId.ToString();
             *
             *      if (siteMinderBusinessGuid != null) // BCeID user
             *      {
             *          var account = await _dynamicsClient.GetAccountBySiteminderBusinessGuid(siteMinderBusinessGuid);
             *          if (account != null && account.Accountid != null)
             *          {
             *              userSettings.AccountId = account.Accountid;
             *              userSettings.AuthenticatedUser.AccountId = Guid.Parse(account.Accountid);
             *          }
             *      }
             *  }
             *
             *  if (!hostingEnv.IsProduction() && (isDeveloperLogin || isBCSCDeveloperLogin))
             *  {
             *      _logger.LogError("DEV MODE Setting identity and creating session for: " + userId);
             *
             *      if (isDeveloperLogin)
             *      {
             *          userSettings.BusinessLegalName = devCompanyId + " BusinessProfileName";
             *          userSettings.UserDisplayName = userId + " BCeIDContactType";
             *
             *          // add generated guids
             *          userSettings.SiteMinderBusinessGuid = GuidUtility.CreateIdForDynamics("account", userSettings.BusinessLegalName).ToString();
             *          userSettings.SiteMinderGuid = GuidUtility.CreateIdForDynamics("contact", userSettings.UserDisplayName).ToString();
             *      }
             *      else if (isBCSCDeveloperLogin)
             *      {
             *          userSettings.BusinessLegalName = null;
             *          userSettings.UserDisplayName = userId + " Associate";
             *
             *          // add generated guids
             *          userSettings.SiteMinderBusinessGuid = null;
             *          userSettings.SiteMinderGuid = GuidUtility.CreateIdForDynamics("bcsc", userSettings.UserDisplayName).ToString();
             *      }
             *
             *      if (userSettings.IsNewUserRegistration)
             *      {
             *          if (isDeveloperLogin)
             *          {
             *              // add generated guids
             *              userSettings.AccountId = userSettings.SiteMinderBusinessGuid;
             *              userSettings.ContactId = userSettings.SiteMinderGuid;
             *          }
             *          else if (isBCSCDeveloperLogin)
             *          {
             *              // set to null for now
             *              userSettings.AccountId = null;
             *              userSettings.ContactId = null;
             *          }
             *
             *          _logger.LogDebug("New user registration:" + userSettings.UserDisplayName);
             *          _logger.LogDebug("userSettings.SiteMinderBusinessGuid:" + userSettings.SiteMinderBusinessGuid);
             *          _logger.LogDebug("userSettings.SiteMinderGuid:" + userSettings.SiteMinderGuid);
             *          _logger.LogDebug("userSettings.AccountId:" + userSettings.AccountId);
             *          _logger.LogDebug("userSettings.ContactId:" + userSettings.ContactId);
             *      }
             *      // Set account ID from authenticated user
             *      else if (userSettings.AuthenticatedUser != null)
             *      {
             *          // populate the business GUID.
             *          if (string.IsNullOrEmpty(userSettings.AccountId))
             *          {
             *              userSettings.AccountId = userSettings.AuthenticatedUser.AccountId.ToString();
             *          }
             *          if (string.IsNullOrEmpty(userSettings.ContactId))
             *          {
             *              userSettings.ContactId = userSettings.AuthenticatedUser.ContactId.ToString();
             *          }
             *          _logger.LogDebug("Returning user:"******"userSettings.AccountId:" + userSettings.AccountId);
             *          _logger.LogDebug("userSettings.ContactId:" + userSettings.ContactId);
             *      }
             *  }
             *
             *
             *  // add the worker settings if it is a new user.
             *  if (userSettings.IsNewUserRegistration && userSettings.NewContact == null)
             *  {
             *      userSettings.NewContact = new ViewModels.Contact();
             *      userSettings.NewContact.CopyHeaderValues(context.Request.Headers);
             *  }
             *
             *  // **************************************************
             *  // Update user settings
             *  // **************************************************
             *  UserSettings.SaveUserSettings(userSettings, context);
             *
             *  // done!
             *  principal = userPrincipal;
             *  return AuthenticateResult.Success(new AuthenticationTicket(principal, null, Options.Scheme));
             * }
             * catch (Exception exception)
             * {
             *  _logger.LogError(exception.Message);
             *  Console.WriteLine(exception);
             *  throw;
             * }
             */
            return(AuthenticateResult.Success(new AuthenticationTicket(principal, null, Options.Scheme)));
        }
        /// <summary>
        /// Process Authentication Request
        /// </summary>
        /// <returns></returns>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            // get siteminder headers
            _logger.Debug("Parsing the HTTP headers for SiteMinder authentication credential");


            string userId                 = null;
            string devCompanyId           = null;
            string siteMinderGuid         = "";
            string siteMinderBusinessGuid = "";
            string siteMinderUserType     = "";

            try
            {
                ClaimsPrincipal principal;
                HttpContext     context      = Request.HttpContext;
                UserSettings    userSettings = new UserSettings();

                IConfiguration _configuration = (IConfiguration)context.RequestServices.GetService(typeof(IConfiguration));
                _dynamicsClient = (IDynamicsClient)context.RequestServices.GetService(typeof(IDynamicsClient));

                IWebHostEnvironment hostingEnv = (IWebHostEnvironment)context.RequestServices.GetService(typeof(IWebHostEnvironment));

                // Fail if login disabled
                if (!string.IsNullOrEmpty(_configuration["FEATURE_DISABLE_LOGIN"]))
                {
                    return(AuthenticateResult.Fail(_options.LoginDisabledError));
                }

                // Fail if coming from JS
                if (context.Request.GetDisplayUrl().ToLower().Contains(".js"))
                {
                    return(AuthenticateResult.NoResult());
                }

                // **************************************************
                // Check if the user session is already created
                // **************************************************
                try
                {
                    _logger.Debug("Checking user session");
                    userSettings = UserSettings.ReadUserSettings(context);

                    // fix for cases where AuthenticatedUser contact is empty.
                    if (userSettings?.AuthenticatedUser?.ContactId != null &&
                        userSettings?.AuthenticatedUser?.ContactId == Guid.Empty && !string.IsNullOrEmpty(userSettings?.SiteMinderGuid))
                    {
                        var contact = _dynamicsClient.GetActiveContactByExternalId(userSettings.SiteMinderGuid);
                        if (contact != null)
                        {
                            userSettings.AuthenticatedUser.ContactId = Guid.Parse(contact.Contactid);
                        }
                    }

                    _logger.Debug("UserSettings found: " + userSettings.GetJson());
                }
                catch
                {
                    //do nothing
                    _logger.Debug("No UserSettings found");
                }

                // is user authenticated - if so we're done
                if ((userSettings.UserAuthenticated && string.IsNullOrEmpty(userId)) ||
                    (userSettings.UserAuthenticated && !string.IsNullOrEmpty(userId) &&
                     !string.IsNullOrEmpty(userSettings.UserId) && userSettings.UserId == userId))
                {
                    _logger.Debug("User already authenticated with active session: " + userSettings.UserId);
                    principal = userSettings.AuthenticatedUser.ToClaimsPrincipal(_options.Scheme, userSettings.UserType);
                    return(AuthenticateResult.Success(new AuthenticationTicket(principal, null, Options.Scheme)));
                }

                // **************************************************
                // Check if we have a Dev Environment Cookie
                // **************************************************
                if (!hostingEnv.IsProduction() &&
                    (!string.IsNullOrEmpty(context.Request.Cookies[_options.DevAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Cookies[_options.DevBCSCAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Headers[_options.DevAuthenticationTokenKey]) ||
                     !string.IsNullOrEmpty(context.Request.Headers[_options.DevBCSCAuthenticationTokenKey]))
                    )
                {
                    try
                    {
                        return(await LoginDevUser(context, _dynamicsClient));
                    }
                    catch (Exception ex)
                    {
                        _logger.Information(ex.Message);
                        _logger.Information("Couldn't successfully login as dev user - continuing as regular user");
                    }
                }

                // determine if it is the new bridge entity based flow or the legacy.
                if (!string.IsNullOrEmpty(_configuration["FEATURE_BRIDGE_LOGIN"]))
                {
                    return(await HandleBridgeAuthentication(userSettings, context));
                }
                else
                {
                    return(await HandleLegacyAuthentication(userSettings, context));
                }
            }
            catch (Exception exception)
            {
                _logger.Error(exception.Message);
                throw;
            }
        }
 public virtual Task <PolicyAuthorizationResult> AuthorizeAsync(
     AuthorizationPolicy policy,
     AuthenticateResult authenticationResult,
     HttpContext context,
     object resource)
 => Task.FromResult(PolicyAuthorizationResult.Success());
Beispiel #29
0
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            if (!Request.Headers.ContainsKey("Authorization"))
            {
                return(AuthenticateResult.Fail("Header Not Found."));
            }

            var token = Request.Headers["Authorization"].ToString();

            if (!token.StartsWith(TokenPrefix))
            {
                return(AuthenticateResult.Fail("Invalid header."));
            }

            token = token.Substring(TokenPrefix.Length);

            var maybeUser = AuthenticatedUsers.TryGet(token);

            return(await maybeUser.Match <Task <AuthenticateResult> >(
                       async user =>
            {
                var now = this.nClock.GetCurrentInstant();
                if (user.Expiry < now)
                {
                    try
                    {
                        // Try authenticate again if the timeout has expired.
                        var maybeNewUser = await this.CheckTokenWithGoogle(user.IdToken);

                        if (maybeNewUser.HasValue)
                        {
                            // User is still valid, update user.
                            var newUser = new AuthenticatedUser(token, user.User, now.Plus(this.SessionTimeout));
                            AuthenticatedUsers.AddOrUpdate(token, newUser);
                        }
                        else
                        {
                            // User is no longer valid, remove user.
                            AuthenticatedUsers.Remove(token);
                            return AuthenticateResult.Fail("User not authenticated");
                        }
                    }
                    catch
                    {
                        // Authentication failed for unknown reason, remove user.
                        AuthenticatedUsers.Remove(token);
                        return AuthenticateResult.Fail("User not authenticated");
                    }
                }
                else
                {
                    // Update expiry of user. This means the timeout only expires after an inactivity of this
                    // time, and continued requests keep the session alive.
                    var newUser = new AuthenticatedUser(token, user.User, now.Plus(this.SessionTimeout));
                    AuthenticatedUsers.AddOrUpdate(token, newUser);
                }

                // Authorized from here, set the user identity and return the principal.
                var ticket = new AuthenticationTicket(
                    new ClaimsPrincipal(new ClaimsIdentity(new[]
                {
                    new Claim("Identifier", user.User.Identifier),
                    new Claim("Name", user.User.Name),
                    new Claim("Email", user.User.Email),
                    new Claim("IdToken", user.IdToken),
                },
                                                           AuthHandler.SchemeName)),
                    this.Scheme.Name);
                return AuthenticateResult.Success(ticket);
            },
                       () => Task.FromResult(AuthenticateResult.Fail("User not authenticated."))));
        }
Beispiel #30
0
 protected override Task <AuthenticateResult> HandleAuthenticateAsync()
 {
     return(Task.FromResult(AuthenticateResult.Fail("Failed Authentication")));
 }
Beispiel #31
0
 private void ProcessLoginCallbackForSaml2p(AuthenticateResult externalResult, List <Claim> localClaims, AuthenticationProperties localSignInProps)
 {
 }
Beispiel #32
0
        /// <summary>
        /// Process Authentication Request
        /// </summary>
        /// <returns></returns>
        protected override Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            // get siteminder headers
            _logger.LogDebug("Parsing the HTTP headers for SiteMinder authentication credential");

            SiteMinderAuthOptions options = new SiteMinderAuthOptions();

            try
            {
                ClaimsPrincipal principal;

                HttpContext         context      = Request.HttpContext;
                IDbAppContext       dbAppContext = (DbAppContext)context.RequestServices.GetService(typeof(DbAppContext));
                IHostingEnvironment hostingEnv   = (IHostingEnvironment)context.RequestServices.GetService(typeof(IHostingEnvironment));

                UserSettings userSettings   = new UserSettings();
                string       userId         = "";
                string       siteMinderGuid = "";

                // **************************************************
                // If this is an Error or Authentiation API - Ignore
                // **************************************************
                string url = context.Request.GetDisplayUrl().ToLower();

                if (url.Contains("/authentication/dev") ||
                    url.Contains("/error") ||
                    url.Contains(".map") ||
                    url.Contains(".js"))
                {
                    return(Task.FromResult(AuthenticateResult.NoResult()));
                }

                // **************************************************
                // Check if we have a Dev Environment Cookie
                // **************************************************
                if (hostingEnv.IsDevelopment())
                {
                    string temp = context.Request.Cookies[options.DevAuthenticationTokenKey];

                    if (!string.IsNullOrEmpty(temp))
                    {
                        userId = temp;
                    }
                }

                // **************************************************
                // Check if the user session is already created
                // **************************************************
                try
                {
                    _logger.LogInformation("Checking user session");
                    userSettings = UserSettings.ReadUserSettings(context);
                }
                catch
                {
                    //do nothing
                }

                // is user authenticated - if so we're done
                if ((userSettings.UserAuthenticated && string.IsNullOrEmpty(userId)) ||
                    (userSettings.UserAuthenticated && !string.IsNullOrEmpty(userId) &&
                     !string.IsNullOrEmpty(userSettings.UserId) && userSettings.UserId == userId))
                {
                    _logger.LogInformation("User already authenticated with active session: " + userSettings.UserId);
                    principal = userSettings.HetsUser.ToClaimsPrincipal(options.Scheme);
                    return(Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(principal, null, Options.Scheme))));
                }

                // **************************************************
                // Authenticate based on SiteMinder Headers
                // **************************************************
                _logger.LogDebug("Parsing the HTTP headers for SiteMinder authentication credential");

                if (string.IsNullOrEmpty(userId))
                {
                    userId = context.Request.Headers[options.SiteMinderUserNameKey];
                    if (string.IsNullOrEmpty(userId))
                    {
                        userId = context.Request.Headers[options.SiteMinderUniversalIdKey];
                    }

                    siteMinderGuid = context.Request.Headers[options.SiteMinderUserGuidKey];

                    // **************************************************
                    // Validate credentials
                    // **************************************************
                    if (string.IsNullOrEmpty(userId))
                    {
                        _logger.LogError(options.MissingSiteMinderUserIdError);
                        return(Task.FromResult(AuthenticateResult.Fail(options.MissingSiteMinderGuidError)));
                    }

                    if (string.IsNullOrEmpty(siteMinderGuid))
                    {
                        _logger.LogError(options.MissingSiteMinderGuidError);
                        return(Task.FromResult(AuthenticateResult.Fail(options.MissingSiteMinderGuidError)));
                    }
                }

                // **************************************************
                // Validate credential against database
                // **************************************************
                userSettings.HetsUser = hostingEnv.IsDevelopment()
                    ? dbAppContext.LoadUser(userId)
                    : dbAppContext.LoadUser(userId, siteMinderGuid);

                if (userSettings.HetsUser == null)
                {
                    _logger.LogWarning(options.MissingDbUserIdError + " (" + userId + ")");
                    return(Task.FromResult(AuthenticateResult.Fail(options.MissingDbUserIdError)));
                }

                if (!userSettings.HetsUser.Active)
                {
                    _logger.LogWarning(options.InactivegDbUserIdError + " (" + userId + ")");
                    return(Task.FromResult(AuthenticateResult.Fail(options.InactivegDbUserIdError)));
                }

                // **************************************************
                // Create authenticated user
                // **************************************************
                _logger.LogInformation("Authentication successful: " + userId);
                _logger.LogInformation("Setting identity and creating session for: " + userId);

                // create session info
                userSettings.UserId            = userId;
                userSettings.UserAuthenticated = true;

                // update user settings
                UserSettings.SaveUserSettings(userSettings, context);

                // done!
                principal = userSettings.HetsUser.ToClaimsPrincipal(options.Scheme);
                return(Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(principal, null, Options.Scheme))));
            }
            catch (Exception exception)
            {
                _logger.LogError(exception.Message);
                Console.WriteLine(exception);
                throw;
            }
        }
        public async Task<IHttpActionResult> ResumeLoginFromRedirect()
        {
            Logger.Info("Callback requested to resume login from partial login");

            var user = await GetIdentityFromPartialSignIn();
            if (user == null)
            {
                Logger.Error("no identity from partial login");
                return RedirectToRoute(Constants.RouteNames.Login, null);
            }

            var subject = user.GetSubjectId();
            var name = user.GetName();
            var result = new AuthenticateResult(subject, name);
            
            var method = user.GetAuthenticationMethod();
            var idp = user.GetIdentityProvider();
            var authTime = user.GetAuthenticationTimeEpoch();

            var authorizationReturnUrl = user.Claims.GetValue(Constants.ClaimTypes.AuthorizationReturnUrl);
            
            SignIn(result, method, idp, authTime);

            Logger.InfoFormat("redirecting to: {0}", authorizationReturnUrl);
            return Redirect(authorizationReturnUrl);
        }
        private IHttpActionResult SignInAndRedirect(
            AuthenticateResult authResult,
            string authenticationMethod,
            string identityProvider,
            long authTime = 0)
        {
            logger.Verbose("[AuthenticationController.SignInAndRedirect] called");

            if (authResult == null) throw new ArgumentNullException("authResult");
            if (String.IsNullOrWhiteSpace(authenticationMethod)) throw new ArgumentNullException("authenticationMethod");
            if (String.IsNullOrWhiteSpace(identityProvider)) throw new ArgumentNullException("identityProvider");

            var signInMessage = LoadLoginRequestMessage();

            var issuer = authResult.IsPartialSignIn ?
                Constants.PartialSignInAuthenticationType :
                Constants.PrimaryAuthenticationType;

            var principal = IdentityServerPrincipal.Create(
                authResult.Subject,
                authResult.Name,
                authenticationMethod,
                identityProvider,
                issuer,
                authTime);

            var id = principal.Identities.First();

            if (authResult.IsPartialSignIn)
            {
                // TODO: put original return URL into cookie with a GUID ID
                // and put the ID as route param for the resume URL. then
                // we can always call ClearLoginRequestMessage()
                id.AddClaim(new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, Url.Route(Constants.RouteNames.ResumeLoginFromRedirect, null)));

                // allow redircting code to add claims for target page
                id.AddClaims(authResult.RedirectClaims);
            }

            var ctx = Request.GetOwinContext();
            ctx.Authentication.SignOut(
                Constants.PrimaryAuthenticationType,
                Constants.ExternalAuthenticationType,
                Constants.PartialSignInAuthenticationType);
            ctx.Authentication.SignIn(id);

            if (authResult.IsPartialSignIn)
            {
                logger.Verbose("[AuthenticationController.SignInAndRedirect] partial login requested, redirecting to requested url");

                var uri = new Uri(ctx.Request.Uri, authResult.PartialSignInRedirectPath.Value);
                return Redirect(uri);
            }
            else
            {
                logger.Verbose("[AuthenticationController.SignInAndRedirect] normal login requested, redirecting back to authorization");

                // TODO -- manage this state better if we're doing redirect to custom page
                // would rather the redirect URL from request message put into cookie
                // and named with a nonce, then the resume url + nonce set as claim
                // in principal above so page being redirected to can know what url to return to
                ClearLoginRequestMessage();

                return Redirect(signInMessage.ReturnUrl);
            }
        }
 private void SignIn(
     AuthenticateResult authResult,
     string authenticationMethod,
     string identityProvider,
     long authTime)
 {
     IssueAuthenticationCookie(authResult, authenticationMethod, identityProvider, authTime);
     ClearSignInMessage();
 }
        public async Task<IHttpActionResult> ResumeLoginFromRedirect(string resume)
        {
            Logger.Info("Callback requested to resume login from partial login");

            if (resume.IsMissing())
            {
                Logger.Error("no resumeId passed");
                return RenderErrorPage();
            }

            var user = await GetIdentityFromPartialSignIn();
            if (user == null)
            {
                Logger.Error("no identity from partial login");
                return RenderErrorPage();
            }

            var type = GetClaimTypeForResumeId(resume);
            var resumeClaim = user.FindFirst(type);
            if (resumeClaim == null)
            {
                Logger.Error("no claim matching resumeId");
                return RenderErrorPage();
            }

            var signInId = resumeClaim.Value;
            if (signInId.IsMissing())
            {
                Logger.Error("No signin id found in resume claim");
                return RenderErrorPage();
            }

            var cookie = new MessageCookie<SignInMessage>(Request.GetOwinContext(), this._options);
            var signInMessage = cookie.Read(signInId);
            if (signInMessage == null)
            {
                Logger.Error("No cookie matching signin id found");
                return RenderErrorPage();
            }

            AuthenticateResult result = null;
            var externalProviderClaim = user.FindFirst(Constants.ClaimTypes.ExternalProviderUserId);
            if (externalProviderClaim == null)
            {
                // the user/subject was known, so pass thru (without the redirect claims)
                user.RemoveClaim(user.FindFirst(Constants.ClaimTypes.PartialLoginReturnUrl));
                user.RemoveClaim(user.FindFirst(GetClaimTypeForResumeId(resume)));
                result = new AuthenticateResult(new ClaimsPrincipal(user));
            }
            else
            {
                // the user was not known, we need to re-execute AuthenticateExternalAsync
                // to obtain a subject to proceed
                var provider = externalProviderClaim.Issuer;
                var providerId = externalProviderClaim.Value;
                var externalId = new ExternalIdentity
                {
                    Provider = provider,
                    ProviderId = providerId,
                    Claims = user.Claims
                };

                result = await _userService.AuthenticateExternalAsync(externalId);

                if (result == null)
                {
                    Logger.Warn("user service failed to authenticate external identity");
                    return await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount);
                }

                if (result.IsError)
                {
                    Logger.WarnFormat("user service returned error message: {0}", result.ErrorMessage);
                    return await RenderLoginPage(signInMessage, signInId, result.ErrorMessage);
                }
            }

            return SignInAndRedirect(signInMessage, signInId, result);
        }
        private void IssueAuthenticationCookie(
            AuthenticateResult authResult, 
            string authenticationMethod, 
            string identityProvider, 
            long authTime)
        {
            if (authResult == null) throw new ArgumentNullException("authResult");
            if (String.IsNullOrWhiteSpace(authenticationMethod)) throw new ArgumentNullException("authenticationMethod");
            if (String.IsNullOrWhiteSpace(identityProvider)) throw new ArgumentNullException("identityProvider");
            
            Logger.InfoFormat("logging user in as subject: {0}, name: {1}{2}", authResult.Subject, authResult.Name, authResult.IsPartialSignIn ? " (partial login)" : "");
            
            var issuer = authResult.IsPartialSignIn ?
                Constants.PartialSignInAuthenticationType :
                Constants.PrimaryAuthenticationType;

            var principal = IdentityServerPrincipal.Create(
                authResult.Subject,
                authResult.Name,
                authenticationMethod,
                identityProvider,
                issuer,
                authTime);

            var id = principal.Identities.First();
            if (authResult.IsPartialSignIn)
            {
                // add claim so partial redirect can return here to continue login
                var resumeLoginUrl = Url.Link(Constants.RouteNames.ResumeLoginFromRedirect, null);
                var resumeLoginClaim = new Claim(Constants.ClaimTypes.PartialLoginReturnUrl, resumeLoginUrl);
                id.AddClaim(resumeLoginClaim);

                // store original authorization url as claim
                // so once we result we can return to authorization page
                var signInMessage = LoadSignInMessage();
                var authorizationUrl = signInMessage.ReturnUrl;
                var authorizationUrlClaim = new Claim(Constants.ClaimTypes.AuthorizationReturnUrl, authorizationUrl);
                id.AddClaim(authorizationUrlClaim);

                // allow redircting code to add claims for target page
                id.AddClaims(authResult.RedirectClaims);
            }

            ClearAuthenticationCookies();

            var ctx = Request.GetOwinContext();
            ctx.Authentication.SignIn(id);
        }
Beispiel #38
0
        /// <summary>
        /// Searches the 'Authorization' header for a 'Bearer' token. If the 'Bearer' token is found, it is validated using <see cref="T:Microsoft.IdentityModel.Tokens.TokenValidationParameters" /> set in the options.
        /// </summary>
        /// <returns></returns>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            string    token;
            Exception obj;
            AuthenticationFailedContext authenticationFailedContext;
            int num;

            try
            {
                var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options);
                await Events.MessageReceived(messageReceivedContext);

                if (messageReceivedContext.Result != null)
                {
                    return(messageReceivedContext.Result);
                }
                token = messageReceivedContext.Token;
                if (string.IsNullOrEmpty(token))
                {
                    string header = Request.Headers["Authorization"];
                    if (string.IsNullOrEmpty(header))
                    {
                        return(AuthenticateResult.NoResult());
                    }
                    if (header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
                    {
                        token = header.Substring("Bearer ".Length).Trim();
                    }
                    if (string.IsNullOrEmpty(token))
                    {
                        return(AuthenticateResult.NoResult());
                    }
                }
                if (_configuration == null && Options.ConfigurationManager != null)
                {
                    var configurationAsync = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted);

                    _configuration = configurationAsync;
                }
                var validationParameters1 = Options.TokenValidationParameters.Clone();
                if (_configuration != null)
                {
                    var strArray = new string[1]
                    {
                        _configuration.Issuer
                    };
                    var validationParameters2 = validationParameters1;
                    var validIssuers          = validationParameters1.ValidIssuers;
                    var obj1 = (validIssuers != null ? validIssuers.Concat(strArray) : null) ?? strArray;
                    validationParameters2.ValidIssuers = obj1;
                    var validationParameters3 = validationParameters1;
                    var issuerSigningKeys     = validationParameters1.IssuerSigningKeys;
                    var securityKeys          = (issuerSigningKeys != null ? issuerSigningKeys.Concat(_configuration.SigningKeys) : null) ?? _configuration.SigningKeys;
                    validationParameters3.IssuerSigningKeys = securityKeys;
                }
                List <Exception> exceptionList = null;
                foreach (var securityTokenValidator in Options.SecurityTokenValidators)
                {
                    if (securityTokenValidator.CanReadToken(token))
                    {
                        SecurityToken   securityToken;
                        ClaimsPrincipal claimsPrincipal;
                        try
                        {
                            claimsPrincipal = securityTokenValidator.ValidateToken(token, validationParameters1, out securityToken);
                        }
                        catch (Exception ex)
                        {
                            //Logger.TokenValidationFailed(ex);
                            if (Options.RefreshOnIssuerKeyNotFound && Options.ConfigurationManager != null && ex is SecurityTokenSignatureKeyNotFoundException)
                            {
                                Options.ConfigurationManager.RequestRefresh();
                            }
                            if (exceptionList == null)
                            {
                                exceptionList = new List <Exception>(1);
                            }
                            exceptionList.Add(ex);
                            continue;
                        }
                        //Logger.TokenValidationSucceeded();
                        var validatedContext = new TokenValidatedContext(Context, Scheme, Options);
                        validatedContext.Principal     = claimsPrincipal;
                        validatedContext.SecurityToken = securityToken;
                        var tokenValidatedContext = validatedContext;
                        await Events.TokenValidated(tokenValidatedContext);

                        if (tokenValidatedContext.Result != null)
                        {
                            return(tokenValidatedContext.Result);
                        }
                        if (Options.SaveToken)
                        {
                            tokenValidatedContext.Properties.StoreTokens(new AuthenticationToken[1]
                            {
                                new AuthenticationToken()
                                {
                                    Name  = "access_token",
                                    Value = token
                                }
                            });
                        }
                        tokenValidatedContext.Success();
                        return(tokenValidatedContext.Result);
                    }
                }
                if (exceptionList == null)
                {
                    return(AuthenticateResult.Fail("No SecurityTokenValidator available for token: " + token ?? "[null]"));
                }
                authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
                {
                    Exception = exceptionList.Count == 1 ? exceptionList[0] : new AggregateException(exceptionList)
                };
                await Events.AuthenticationFailed(authenticationFailedContext);

                return(authenticationFailedContext.Result == null?AuthenticateResult.Fail(authenticationFailedContext.Exception) : authenticationFailedContext.Result);
            }
            catch (Exception ex)
            {
                obj = ex;
                num = 1;
            }
            if (num == 1)
            {
                var ex = obj;
                //Logger.ErrorProcessingMessage(ex);
                authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options)
                {
                    Exception = ex
                };
                await Events.AuthenticationFailed(authenticationFailedContext);

                if (authenticationFailedContext.Result != null)
                {
                    return(authenticationFailedContext.Result);
                }
                var source = obj as Exception;
                if (source == null)
                {
                    throw obj;
                }
                ExceptionDispatchInfo.Capture(source).Throw();
                authenticationFailedContext = null;
            }

            return(null);
        }
        public async Task<IHttpActionResult> ResumeLoginFromRedirect()
        {
            logger.Start("[AuthenticationController.ResumeLoginFromRedirect] called");

            var ctx = Request.GetOwinContext();
            var redirectAuthResult = await ctx.Authentication.AuthenticateAsync(Constants.PartialSignInAuthenticationType);
            if (redirectAuthResult == null ||
                redirectAuthResult.Identity == null)
            {
                logger.Verbose("[AuthenticationController.ResumeLoginFromRedirect] no redirect identity - exiting to login page");
                return RedirectToRoute(Constants.RouteNames.Login, null);
            }

            var subject = redirectAuthResult.Identity.GetSubjectId();
            var name = redirectAuthResult.Identity.GetName();

            var result = new AuthenticateResult(subject, name);
            var method = redirectAuthResult.Identity.GetAuthenticationMethod();
            var idp = redirectAuthResult.Identity.GetIdentityProvider();
            var authTime = redirectAuthResult.Identity.GetAuthenticationTimeEpoch();

            return SignInAndRedirect(result, method, idp, authTime);
        }
        protected async override Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            if (this.Context == null)
            {
                return(AuthenticateResult.Fail("Context is Null"));
            }
            if (this.Options == null)
            {
                return(AuthenticateResult.Fail("Options is Null"));
            }
            var token = this.Context.Request.Query[Options.TokenQueryKey].FirstOrDefault();

            if (string.IsNullOrEmpty(token))
            {
                // 地址过滤标识
                var    flag = false;
                string key1 = this.Context.Request.Query["name"];
                if (!string.IsNullOrEmpty(key1) && key1 == "admin")
                {
                    flag = true;
                }

                if (flag)
                {
                    ClaimsIdentity id = new ClaimsIdentity(APIScheme, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
                    id.AddClaim(new Claim(ClaimTypes.Role, key1));
                    id.AddClaim(new Claim(ClaimTypes.Name, key1));
                    //id.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, "admin"));


                    ClaimsPrincipal      p     = new ClaimsPrincipal(id);
                    AuthenticationTicket tiket = new AuthenticationTicket(p, APIScheme);
                    this.Context.Items.Add(APIUserKey, _format.Protect(tiket));
                    return(AuthenticateResult.Success(tiket));
                }
                return(AuthenticateResult.Fail("暂无权限"));//.NoResult();
            }

            if (string.IsNullOrEmpty(token))
            {
                return(AuthenticateResult.NoResult());
            }


            int index = token.IndexOf('1');

            if (index == -1)
            {
                return(AuthenticateResult.Fail("format wrong"));
            }

            var user = token.Substring(index + 1);

            var userEntity = await _userManager.FindByNameAsync(user);

            if (userEntity == null)
            {
                return(AuthenticateResult.Fail("user is not found"));
            }



            var ticketStr = await _userManager.GetAuthenticationTokenAsync(userEntity, "APILOGIN", token);

            if (string.IsNullOrEmpty(ticketStr))
            {
                return(AuthenticateResult.NoResult());
            }

            var tokenObj = _format.Unprotect(ticketStr);

            if (tokenObj == null)
            {
                return(AuthenticateResult.NoResult());
            }
            // 验证过期时间
            if (tokenObj.Properties.ExpiresUtc.HasValue)
            {
                if (tokenObj.Properties.ExpiresUtc < base.Clock.UtcNow)
                {
                    return(AuthenticateResult.Fail("Ticket Expire"));
                }
            }

            if (tokenObj.Principal == null)
            {
                return(AuthenticateResult.Fail("NO Principal"));
            }

            this.Context.Items.Add(APIUserKey, tokenObj.Principal);
            this.Context.Items.Add("ticket", token);
            _log.LogDebug($"Get a token ticket user is {tokenObj?.Principal?.Identity?.Name}");
            return(AuthenticateResult.Success(tokenObj));
        }
 private static void Describe(IOwinResponse res, AuthenticateResult result)
 {
     res.StatusCode = 200;
     res.ContentType = "text/xml";
     var xml = new XElement("xml");
     if (result != null && result.Identity != null)
     {
         xml.Add(result.Identity.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value))));
     }
     if (result != null && result.Properties != null)
     {
         xml.Add(result.Properties.Dictionary.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value))));
     }
     using (var memory = new MemoryStream())
     {
         using (var writer = new XmlTextWriter(memory, Encoding.UTF8))
         {
             xml.WriteTo(writer);
         }
         res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length);
     }
 }
Beispiel #42
0
        protected async override Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            var authorizationHeader = this.Request.Headers["Authorization"];

            var remoteIPAddress = this.Context.Connection.RemoteIpAddress;

            this.Logger?.LogDebug(
                "Request came from remote IP Address: {RemoteIPAddress}. Continuing with auth check.",
                remoteIPAddress.ToJson());

            if (!authorizationHeader.Any())
            {
                this.Logger?.LogWarning(
                    "Failing authentication from IP {RemoteIPAddress} for application: {Reason}",
                    remoteIPAddress.ToJson(),
                    "No authorization header found");
                return(AuthenticateResult.Fail("No authorization header found"));
            }

            if (!TryGetHmacAuthenticationParameter(this.Logger, remoteIPAddress, authorizationHeader[0] ?? string.Empty, out var parameter))
            {
                this.Logger?.LogWarning("Failing authentication from IP {RemoteIPAddress}: {Reason}",
                                        remoteIPAddress.ToJson(),
                                        "Invalid HMAC authentication parameter");
                return(AuthenticateResult.Fail("Invalid HMAC authentication parameter"));
            }

            if (!this.ApplicationSecretStore.TryGetValue(parameter.ApplicationKey, out var applicationSecret))
            {
                this.Logger?.LogWarning("Failing authentication from IP {RemoteIPAddress}: {Reason}. Parameters: {Parameters}",
                                        remoteIPAddress.ToJson(),
                                        "No secret found for application key",
                                        parameter.ToJson());
                return(AuthenticateResult.Fail("No secret found for application key"));
            }

            if (!IsRequestFresh(parameter, out var freshnessIndicator))
            {
                this.Logger?.LogWarning(
                    "Failing authentication from IP {RemoteIPAddress}: {Reason}. Parameters: {Parameters}. Freshness Indicator: {FreshnessIndicator}",
                    remoteIPAddress.ToJson(),
                    "HMAC authentication request is not fresh",
                    parameter.ToJson(),
                    freshnessIndicator.ToJson());
                return(AuthenticateResult.Fail("HMAC authentication request is not fresh"));
            }

            var includeBodyInHash = this.Request.ContentLength.HasValue && this.Request.ContentLength.Value > 0;
            var requestBody       = includeBodyInHash ? await ReadRequestBody(this.Request).ConfigureAwait(false) : string.Empty;

            var displayUrl = this.Request.GetDisplayUrl();

            var hash = HmacHashGenerator.Generate(
                parameter,
                applicationSecret,
                displayUrl,
                requestBody);

            if (hash != parameter.Hash)
            {
                this.Logger?.LogWarning(
                    "Failing authentication from IP {RemoteIPAddress}: {Reason}. DisplayUrl: {DisplayUrl}. Parameters: {Parameters}. Includes body: {IncludeBodyInHash}.",
                    remoteIPAddress.ToJson(),
                    "HMAC request hashes do not match",
                    displayUrl,
                    parameter.ToJson(),
                    includeBodyInHash);
                return(AuthenticateResult.Fail("HMAC request hashes do not match"));
            }

            this.Logger?.LogDebug(
                "HMAC authentication from IP {RemoteIPAddress} looks good. Building claims principal for User: {User}, ApplicationKey: {Application}, Time: {Time}.",
                remoteIPAddress.ToJson(),
                parameter.AuthenticatedUser,
                parameter.ApplicationKey,
                parameter.Time);

            var properties = new AuthenticationProperties();

            properties.Items[nameof(HmacAuthenticationParameter.ApplicationKey)]    = parameter.ApplicationKey;
            properties.Items[nameof(HmacAuthenticationParameter.AuthenticatedUser)] = parameter.AuthenticatedUser;
            properties.Items[nameof(HmacAuthenticationParameter.Time)] = parameter.Time;

            ClaimsIdentity identity = new GenericIdentity(parameter.AuthenticatedUser, HmacSchemeName);

            if (this.ClaimsProvider == null)
            {
                this.Logger?.LogWarning("The claims provider is null. Proceeding without attaching claims to identity.");
            }
            else
            {
                this.Logger?.LogDebug("Attaching claims to identity.");
                this.ClaimsProvider.AddClaimsTo(identity, properties);

                if (identity.Claims.Any())
                {
                    this.Logger?.LogDebug("Claims were successfully attached.");
                }
                else
                {
                    this.Logger?.LogWarning("No claims were attached by the claims provider.");
                }
            }

            var user = new ClaimsPrincipal(identity);

            this.Logger?.LogDebug("Returning success with claims principal.");

            return(AuthenticateResult.Success(new AuthenticationTicket(user, properties, HmacSchemeName)));
        }
 private void RaiseLocalLoginSuccessEvent(string username, SignInMessage signInMessage, AuthenticateResult authResult)
 {
     _events.RaiseLocalLoginSuccessEvent(Request.GetOwinEnvironment(), username, signInMessage, authResult);
 }
Beispiel #44
0
    private static async Task <TestServer> CreateServer(Action <IServiceCollection> configureServices = null, Func <HttpContext, Task> testpath = null, Uri baseAddress = null, bool testCore = false)
    {
        var host = new HostBuilder()
                   .ConfigureWebHost(builder =>
                                     builder.Configure(app =>
        {
            app.UseAuthentication();
            app.Use(async(context, next) =>
            {
                var req           = context.Request;
                var res           = context.Response;
                var userManager   = context.RequestServices.GetRequiredService <UserManager <PocoUser> >();
                var roleManager   = context.RequestServices.GetRequiredService <RoleManager <PocoRole> >();
                var signInManager = context.RequestServices.GetRequiredService <SignInManager <PocoUser> >();
                PathString remainder;
                if (req.Path == new PathString("/normal"))
                {
                    res.StatusCode = 200;
                }
                else if (req.Path == new PathString("/createMe"))
                {
                    var user   = new PocoUser("hao");
                    var result = await userManager.CreateAsync(user, TestPassword);
                    if (result.Succeeded)
                    {
                        result = await roleManager.CreateAsync(new PocoRole("role"));
                    }
                    if (result.Succeeded)
                    {
                        result = await userManager.AddToRoleAsync(user, "role");
                    }
                    res.StatusCode = result.Succeeded ? 200 : 500;
                }
                else if (req.Path == new PathString("/createSimple"))
                {
                    var result     = await userManager.CreateAsync(new PocoUser("simple"), "aaaaaa");
                    res.StatusCode = result.Succeeded ? 200 : 500;
                }
                else if (req.Path == new PathString("/signoutEverywhere"))
                {
                    var user       = await userManager.FindByNameAsync("hao");
                    var result     = await userManager.UpdateSecurityStampAsync(user);
                    res.StatusCode = result.Succeeded ? 200 : 500;
                }
                else if (req.Path.StartsWithSegments(new PathString("/pwdLogin"), out remainder))
                {
                    var isPersistent = bool.Parse(remainder.Value.AsSpan(1));
                    var result       = await signInManager.PasswordSignInAsync("hao", TestPassword, isPersistent, false);
                    res.StatusCode   = result.Succeeded ? 200 : 500;
                }
                else if (req.Path == new PathString("/twofactorRememeber"))
                {
                    var user = await userManager.FindByNameAsync("hao");
                    await signInManager.RememberTwoFactorClientAsync(user);
                    res.StatusCode = 200;
                }
                else if (req.Path == new PathString("/isTwoFactorRememebered"))
                {
                    var user       = await userManager.FindByNameAsync("hao");
                    var result     = await signInManager.IsTwoFactorClientRememberedAsync(user);
                    res.StatusCode = result ? 200 : 500;
                }
                else if (req.Path == new PathString("/hasTwoFactorUserId"))
                {
                    var result     = await context.AuthenticateAsync(IdentityConstants.TwoFactorUserIdScheme);
                    res.StatusCode = result.Succeeded ? 200 : 500;
                }
                else if (req.Path == new PathString("/me"))
                {
                    await DescribeAsync(res, AuthenticateResult.Success(new AuthenticationTicket(context.User, null, "Application")));
                }
                else if (req.Path.StartsWithSegments(new PathString("/me"), out remainder))
                {
                    var auth = await context.AuthenticateAsync(remainder.Value.Substring(1));
                    await DescribeAsync(res, auth);
                }
                else if (req.Path == new PathString("/testpath") && testpath != null)
                {
                    await testpath(context);
                }
                else
                {
                    await next(context);
                }
            });
        })
                                     .ConfigureServices(services =>
        {
            if (testCore)
            {
                services.AddIdentityCore <PocoUser>()
                .AddRoles <PocoRole>()
                .AddSignInManager()
                .AddDefaultTokenProviders();
                services.AddAuthentication(IdentityConstants.ApplicationScheme).AddIdentityCookies();
            }
            else
            {
                services.AddIdentity <PocoUser, PocoRole>().AddDefaultTokenProviders();
            }
            var store = new InMemoryStore <PocoUser, PocoRole>();
            services.AddSingleton <IUserStore <PocoUser> >(store);
            services.AddSingleton <IRoleStore <PocoRole> >(store);
            configureServices?.Invoke(services);
        })
                                     .UseTestServer())
                   .Build();
        await host.StartAsync();

        var server = host.GetTestServer();

        server.BaseAddress = baseAddress;
        return(server);
    }
        private IHttpActionResult SignInAndRedirect(SignInMessage signInMessage, string signInMessageId, AuthenticateResult authResult, bool? rememberMe = null)
        {
            IssueAuthenticationCookie(signInMessageId, authResult, rememberMe);
            sessionCookie.IssueSessionId();

            var redirectUrl = GetRedirectUrl(signInMessage, authResult);
            Logger.InfoFormat("redirecting to: {0}", redirectUrl);
            return Redirect(redirectUrl);
        }
        public async Task <IHttpActionResult> ResumeLoginFromRedirect(string resume)
        {
            Logger.Info("Callback requested to resume login from partial login");

            if (resume.IsMissing())
            {
                Logger.Error("no resumeId passed");
                return(RenderErrorPage());
            }

            var user = await GetIdentityFromPartialSignIn();

            if (user == null)
            {
                Logger.Error("no identity from partial login");
                return(RenderErrorPage());
            }

            var type        = GetClaimTypeForResumeId(resume);
            var resumeClaim = user.FindFirst(type);

            if (resumeClaim == null)
            {
                Logger.Error("no claim matching resumeId");
                return(RenderErrorPage());
            }

            var signInId = resumeClaim.Value;

            if (signInId.IsMissing())
            {
                Logger.Error("No signin id found in resume claim");
                return(RenderErrorPage());
            }

            var cookie        = new MessageCookie <SignInMessage>(Request.GetOwinContext(), this._options);
            var signInMessage = cookie.Read(signInId);

            if (signInMessage == null)
            {
                Logger.Error("No cookie matching signin id found");
                return(RenderErrorPage());
            }

            AuthenticateResult result = null;
            var externalProviderClaim = user.FindFirst(Constants.ClaimTypes.ExternalProviderUserId);

            if (externalProviderClaim == null)
            {
                // the user/subject was known, so pass thru (without the redirect claims)
                user.RemoveClaim(user.FindFirst(Constants.ClaimTypes.PartialLoginReturnUrl));
                user.RemoveClaim(user.FindFirst(GetClaimTypeForResumeId(resume)));
                result = new AuthenticateResult(new ClaimsPrincipal(user));
            }
            else
            {
                // the user was not known, we need to re-execute AuthenticateExternalAsync
                // to obtain a subject to proceed
                var provider   = externalProviderClaim.Issuer;
                var providerId = externalProviderClaim.Value;
                var externalId = new ExternalIdentity
                {
                    Provider   = provider,
                    ProviderId = providerId,
                    Claims     = user.Claims
                };

                result = await _userService.AuthenticateExternalAsync(externalId);

                if (result == null)
                {
                    Logger.Warn("user service failed to authenticate external identity");
                    return(await RenderLoginPage(signInMessage, signInId, Messages.NoMatchingExternalAccount));
                }

                if (result.IsError)
                {
                    Logger.WarnFormat("user service returned error message: {0}", result.ErrorMessage);
                    return(await RenderLoginPage(signInMessage, signInId, result.ErrorMessage));
                }
            }

            return(SignInAndRedirect(signInMessage, signInId, result));
        }
        private Uri GetRedirectUrl(SignInMessage signInMessage, AuthenticateResult authResult)
        {
            if (signInMessage == null) throw new ArgumentNullException("signInMessage");
            if (authResult == null) throw new ArgumentNullException("authResult");

            if (authResult.IsPartialSignIn)
            {
                var path = authResult.PartialSignInRedirectPath;
                if (path.StartsWith("~/"))
                {
                    path = path.Substring(2);
                    path = Request.GetIdentityServerBaseUrl() + path;
                }
                var host = new Uri(context.GetIdentityServerHost());
                return new Uri(host, path);
            }
            else
            {
                return new Uri(signInMessage.ReturnUrl);
            }
        }
        private IHttpActionResult SignInAndRedirect(SignInMessage signInMessage, string signInMessageId, AuthenticateResult authResult, bool?rememberMe = null)
        {
            IssueAuthenticationCookie(signInMessage, signInMessageId, authResult, rememberMe);

            var redirectUrl = GetRedirectUrl(signInMessage, authResult);

            Logger.InfoFormat("redirecting to: {0}", redirectUrl);
            return(Redirect(redirectUrl));
        }