public async Task When_Passing_Null_Parameter_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            InitializeFakeObjects();

            // ACT & ASSERT
            await Assert.ThrowsAsync <ArgumentNullException>(() => _authenticateHelper.ProcessRedirection(null, null, null, null));
        }
        public async Task <LoginPwdAuthenticateResult> Execute(LoginPasswordAuthParameter parameter, AuthorizationParameter authorizationParameter, string code, string issuerName)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

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


            var resourceOwner = await _resourceOwnerAuthenticateHelper.Authenticate(parameter.Login, parameter.Password, new[] { Constants.AMR }).ConfigureAwait(false);

            if (resourceOwner == null)
            {
                throw new IdentityServerAuthenticationException("the resource owner credentials are not correct");
            }

            var claims = resourceOwner.Claims == null ? new List <Claim>() : resourceOwner.Claims.ToList();

            claims.Add(new Claim(ClaimTypes.AuthenticationInstant, DateTimeOffset.UtcNow.ConvertToUnixTimestamp().ToString(CultureInfo.InvariantCulture), ClaimValueTypes.Integer));
            return(new LoginPwdAuthenticateResult
            {
                ActionResult = await _authenticateHelper.ProcessRedirection(authorizationParameter, code, resourceOwner.Id, claims, issuerName).ConfigureAwait(false),
                Claims = claims
            });
        }
        /// <summary>
        /// Returns an action result to the controller's action.
        /// 1). Redirect to the consent screen if the user is authenticated AND the request doesn't contain a login prompt.
        /// 2). Do nothing
        /// </summary>
        /// <param name="authorizationParameter">The parameter</param>
        /// <param name="resourceOwnerPrincipal">Resource owner principal</param>
        /// <param name="code">Encrypted parameter</param>
        /// <returns>Action result to the controller's action</returns>
        public async Task <ActionResult> Execute(
            AuthorizationParameter authorizationParameter,
            ClaimsPrincipal resourceOwnerPrincipal,
            string code)
        {
            if (authorizationParameter == null)
            {
                throw new ArgumentNullException("authorizationParameter");
            }

            var resourceOwnerIsAuthenticated = resourceOwnerPrincipal.IsAuthenticated();
            var promptParameters             = _parameterParserHelper.ParsePrompts(authorizationParameter.Prompt);

            // 1).
            if (resourceOwnerIsAuthenticated &&
                promptParameters != null &&
                !promptParameters.Contains(PromptParameter.login))
            {
                var subject = resourceOwnerPrincipal.GetSubject();
                var claims  = resourceOwnerPrincipal.Claims.ToList();
                return(await _authenticateHelper.ProcessRedirection(authorizationParameter,
                                                                    code,
                                                                    subject,
                                                                    claims));
            }

            // 2).
            return(_actionResultFactory.CreateAnEmptyActionResultWithNoEffect());
        }
        public async Task <LocalOpenIdAuthenticationResult> Execute(LocalAuthenticateParameter localAuthenticateParameter, AuthorizationParameter authorizationParameter, string code,
                                                                    string imagePath, string hostUrl)
        {
            if (localAuthenticateParameter == null)
            {
                throw new ArgumentNullException(nameof(localAuthenticateParameter));
            }

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

            var resourceOwner = await _localAuthenticateAction.Execute(localAuthenticateParameter, imagePath, hostUrl);

            if (resourceOwner == null)
            {
                throw new IdentityServerAuthenticationException("the resource owner credentials are not correct");
            }

            var claims = resourceOwner.Claims == null ? new List <Claim>() : resourceOwner.Claims.ToList();

            claims.Add(new Claim(ClaimTypes.AuthenticationInstant,
                                 DateTimeOffset.UtcNow.ConvertToUnixTimestamp().ToString(CultureInfo.InvariantCulture),
                                 ClaimValueTypes.Integer));
            return(new LocalOpenIdAuthenticationResult
            {
                ActionResult = await _authenticateHelper.ProcessRedirection(authorizationParameter,
                                                                            code,
                                                                            resourceOwner.Id,
                                                                            claims),
                Claims = claims
            });
        }
示例#5
0
        public async Task <ExternalOpenIdAuthenticationResult> Execute(
            List <Claim> claims,
            AuthorizationParameter authorizationParameter,
            string code)
        {
            // 1. Check parameters.
            if (claims == null || !claims.Any())
            {
                throw new ArgumentNullException(nameof(claims));
            }

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

            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentNullException(nameof(code));
            }

            // 2. Subject cannot be extracted.
            var subject = claims.GetSubject();

            if (string.IsNullOrWhiteSpace(subject))
            {
                throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode,
                                                  ErrorDescriptions.NoSubjectCanBeExtracted);
            }

            // 3. Create the resource owner if needed.
            var resourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject);

            if (resourceOwner == null)
            {
                var standardClaims = await _claimRepository.GetAllAsync();

                resourceOwner = new ResourceOwner
                {
                    Id                      = subject,
                    IsLocalAccount          = false,
                    TwoFactorAuthentication = TwoFactorAuthentications.NONE,
                    Claims                  = claims.Where(c => standardClaims.Any(sc => sc == c.Type)).ToList()
                };
                if (!resourceOwner.Claims.Any(c => c.Type == Jwt.Constants.StandardResourceOwnerClaimNames.Subject))
                {
                    resourceOwner.Claims.Add(new Claim(Jwt.Constants.StandardResourceOwnerClaimNames.Subject, subject));
                }

                await _resourceOwnerRepository.InsertAsync(resourceOwner);
            }
            return(new ExternalOpenIdAuthenticationResult
            {
                ActionResult = await _authenticateHelper.ProcessRedirection(authorizationParameter,
                                                                            code,
                                                                            "subject",
                                                                            claims),
                Claims = resourceOwner.Claims
            });
        }
示例#6
0
        public async Task <ActionResult> LoginCallbackOpenId(string code, string error)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentNullException("code");
            }

            // 1 : retrieve the request from the cookie
            var cookieName = string.Format(ExternalAuthenticateCookieName, code);
            var request    = Request.Cookies[string.Format(ExternalAuthenticateCookieName, code)];

            if (request == null)
            {
                throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode, ErrorDescriptions.TheRequestCannotBeExtractedFromTheCookie);
            }

            // 2 : remove the cookie
            Response.Cookies.Append(cookieName, string.Empty,
                                    new CookieOptions
            {
                Expires = DateTime.UtcNow.AddDays(-1)
            });

            // 3 : Raise an exception is there's an authentication error
            if (!string.IsNullOrWhiteSpace(error))
            {
                throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode, string.Format(ErrorDescriptions.AnErrorHasBeenRaisedWhenTryingToAuthenticate, error));
            }

            // 4. Check if the user is authenticated
            var authenticatedUser = await _authenticationService.GetAuthenticatedUser(this, Host.Constants.CookieNames.ExternalCookieName).ConfigureAwait(false);

            if (authenticatedUser == null ||
                !authenticatedUser.Identity.IsAuthenticated ||
                !(authenticatedUser.Identity is ClaimsIdentity))
            {
                throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode, ErrorDescriptions.TheUserNeedsToBeAuthenticated);
            }

            // 5. Rerieve the claims & insert the resource owner if needed.
            var claimsIdentity = authenticatedUser.Identity as ClaimsIdentity;
            var claims         = authenticatedUser.Claims.ToList();
            var resourceOwner  = await _profileActions.GetResourceOwner(authenticatedUser.GetSubject()).ConfigureAwait(false);

            string sub = string.Empty;

            if (resourceOwner == null)
            {
                try
                {
                    sub = await AddExternalUser(authenticatedUser).ConfigureAwait(false);
                }
                catch (IdentityServerException ex)
                {
                    return(RedirectToAction("Index", "Error", new { code = ex.Code, message = ex.Message, area = "Shell" }));
                }
                catch (Exception ex)
                {
                    return(RedirectToAction("Index", "Error", new { code = ErrorCodes.InternalError, message = ex.Message, area = "Shell" }));
                }
            }

            if (resourceOwner != null)
            {
                claims = resourceOwner.Claims.ToList();
            }
            else
            {
                var nameIdentifier = claims.First(c => c.Type == ClaimTypes.NameIdentifier);
                claims.Remove(nameIdentifier);
                claims.Add(new Claim(ClaimTypes.NameIdentifier, sub));
            }

            var subject = claims.GetSubject();
            // 6. Try to authenticate the resource owner & returns the claims.
            var authorizationRequest = _dataProtector.Unprotect <AuthorizationRequest>(request);
            var issuerName           = Request.GetAbsoluteUriWithVirtualPath();
            var actionResult         = await _authenticateHelper.ProcessRedirection(authorizationRequest.ToParameter(), request, subject, claims, issuerName).ConfigureAwait(false);

            // 7. Store claims into new cookie
            if (actionResult != null)
            {
                await SetLocalCookie(claims.ToOpenidClaims(), authorizationRequest.SessionId).ConfigureAwait(false);

                await _authenticationService.SignOutAsync(HttpContext, Host.Constants.CookieNames.ExternalCookieName, new Microsoft.AspNetCore.Authentication.AuthenticationProperties()).ConfigureAwait(false);

                LogAuthenticateUser(actionResult, authorizationRequest.ProcessId);
                return(this.CreateRedirectionFromActionResult(actionResult, authorizationRequest));
            }

            return(RedirectToAction("OpenId", "Authenticate", new { code = code }));
        }
        public async Task <ActionResult> SendCode(CodeViewModel codeViewModel)
        {
            if (codeViewModel == null)
            {
                throw new ArgumentNullException(nameof(codeViewModel));
            }

            ViewBag.IsAuthenticated = false;
            codeViewModel.Validate(ModelState);
            if (!ModelState.IsValid)
            {
                await TranslateView(DefaultLanguage).ConfigureAwait(false);

                return(View(codeViewModel));
            }

            // 1. Check user is authenticated
            var authenticatedUser = await _authenticationService.GetAuthenticatedUser(this, Host.Constants.CookieNames.TwoFactorCookieName).ConfigureAwait(false);

            if (authenticatedUser == null || authenticatedUser.Identity == null || !authenticatedUser.Identity.IsAuthenticated)
            {
                throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode, ErrorDescriptions.TwoFactorAuthenticationCannotBePerformed);
            }

            // 2. Resend the confirmation code.
            if (codeViewModel.Action == CodeViewModel.RESEND_ACTION)
            {
                await TranslateView(DefaultLanguage).ConfigureAwait(false);

                var resourceOwner = await _userActions.GetUser(authenticatedUser).ConfigureAwait(false);

                var claim = resourceOwner.Claims.FirstOrDefault(c => c.Type == codeViewModel.ClaimName);
                if (claim != null)
                {
                    resourceOwner.Claims.Remove(claim);
                }

                resourceOwner.Claims.Add(new Claim(codeViewModel.ClaimName, codeViewModel.ClaimValue));
                var claimsLst = resourceOwner.Claims.Select(c => new ClaimAggregate(c.Type, c.Value));
                await _userActions.UpdateClaims(authenticatedUser.GetSubject(), claimsLst).ConfigureAwait(false);

                string code;
                try
                {
                    code = await _authenticateActions.GenerateAndSendCode(authenticatedUser.GetSubject()).ConfigureAwait(false);

                    _simpleIdentityServerEventSource.GetConfirmationCode(code);
                }
                catch
                {
                    ModelState.AddModelError("message_error", "An internal error occured while trying to send the confirmation code");
                }

                return(View(codeViewModel));
            }

            // 3. Validate the confirmation code
            if (!await _authenticateActions.ValidateCode(codeViewModel.Code).ConfigureAwait(false))
            {
                await TranslateView(DefaultLanguage).ConfigureAwait(false);

                ModelState.AddModelError("Code", "confirmation code is not valid");
                _simpleIdentityServerEventSource.ConfirmationCodeNotValid(codeViewModel.Code);
                return(View(codeViewModel));
            }

            // 4. Remove the code
            if (!await _authenticateActions.RemoveCode(codeViewModel.Code).ConfigureAwait(false))
            {
                await TranslateView(DefaultLanguage).ConfigureAwait(false);

                ModelState.AddModelError("Code", "an error occured while trying to remove the code");
                return(View(codeViewModel));
            }

            // 5. Authenticate the resource owner
            await _authenticationService.SignOutAsync(HttpContext, Host.Constants.CookieNames.TwoFactorCookieName, new AuthenticationProperties()).ConfigureAwait(false);

            // 6. Redirect the user agent
            if (!string.IsNullOrWhiteSpace(codeViewModel.AuthRequestCode))
            {
                var request = _dataProtector.Unprotect <AuthorizationRequest>(codeViewModel.AuthRequestCode);
                await SetLocalCookie(authenticatedUser.Claims, request.SessionId).ConfigureAwait(false);

                var issuerName   = Request.GetAbsoluteUriWithVirtualPath();
                var actionResult = await _authenticateHelper.ProcessRedirection(request.ToParameter(), codeViewModel.AuthRequestCode, authenticatedUser.GetSubject(), authenticatedUser.Claims.ToList(), issuerName).ConfigureAwait(false);

                LogAuthenticateUser(actionResult, request.ProcessId);
                var result = this.CreateRedirectionFromActionResult(actionResult, request);
                return(result);
            }
            else
            {
                await SetLocalCookie(authenticatedUser.Claims, Guid.NewGuid().ToString()).ConfigureAwait(false);
            }

            // 7. Redirect the user agent to the User view.
            return(RedirectToAction("Index", "User", new { area = "UserManagement" }));
        }
示例#8
0
        public async Task <ActionResult> LoginCallbackOpenId(string code, string error)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentNullException("code");
            }

            // 1 : retrieve the request from the cookie
            var cookieName = string.Format(ExternalAuthenticateCookieName, code);
            var request    = Request.Cookies[string.Format(ExternalAuthenticateCookieName, code)];

            if (request == null)
            {
                throw new IdentityServerException(SimpleIdentityServer.Core.Errors.ErrorCodes.UnhandledExceptionCode,
                                                  SimpleIdentityServer.Core.Errors.ErrorDescriptions.TheRequestCannotBeExtractedFromTheCookie);
            }

            // 2 : remove the cookie
            Response.Cookies.Append(cookieName, string.Empty,
                                    new CookieOptions {
                Expires = DateTime.UtcNow.AddDays(-1)
            });

            // 3 : Raise an exception is there's an authentication error
            if (!string.IsNullOrWhiteSpace(error))
            {
                throw new IdentityServerException(
                          SimpleIdentityServer.Core.Errors.ErrorCodes.UnhandledExceptionCode,
                          string.Format(SimpleIdentityServer.Core.Errors.ErrorDescriptions.AnErrorHasBeenRaisedWhenTryingToAuthenticate, error));
            }

            // 4. Check if the user is authenticated
            var authenticatedUser = await _authenticationService.GetAuthenticatedUser(this, _authenticateOptions.ExternalCookieName);

            if (authenticatedUser == null ||
                !authenticatedUser.Identity.IsAuthenticated ||
                !(authenticatedUser.Identity is ClaimsIdentity))
            {
                throw new IdentityServerException(
                          SimpleIdentityServer.Core.Errors.ErrorCodes.UnhandledExceptionCode,
                          SimpleIdentityServer.Core.Errors.ErrorDescriptions.TheUserNeedsToBeAuthenticated);
            }

            // 5. Rerieve the claims
            var claimsIdentity = authenticatedUser.Identity as ClaimsIdentity;
            var claims         = claimsIdentity.Claims.ToList();
            var subject        = claims.GetSubject();

            // 6. Try to authenticate the resource owner & returns the claims.
            var authorizationRequest = _dataProtector.Unprotect <AuthorizationRequest>(request);
            var actionResult         = await _authenticateHelper.ProcessRedirection(authorizationRequest.ToParameter(), request, subject, claims);

            // 7. Store claims into new cookie
            if (actionResult != null)
            {
                await SetLocalCookie(claims.ToOpenidClaims(), authorizationRequest.SessionId);

                await _authenticationService.SignOutAsync(HttpContext, _authenticateOptions.ExternalCookieName, new Microsoft.AspNetCore.Authentication.AuthenticationProperties());

                LogAuthenticateUser(actionResult, authorizationRequest.ProcessId);
                return(this.CreateRedirectionFromActionResult(actionResult, authorizationRequest));
            }

            return(RedirectToAction("OpenId", "Authenticate", new { code = code }));
        }