示例#1
0
        public async Task <Bitmap> Handle(string id, string claimName, CancellationToken cancellationToken)
        {
            OAuthUser user;

            if (!string.IsNullOrWhiteSpace(claimName))
            {
                user = await _oauthUserRepository.FindOAuthUserByClaim(claimName, id, cancellationToken);
            }
            else
            {
                user = await _oauthUserRepository.FindOAuthUserByLogin(id, cancellationToken);
            }

            if (user == null)
            {
                _logger.LogError($"the user '{id}' doesn't exist");
                throw new OAuthUserNotFoundException(ErrorCodes.INVALID_REQUEST, string.Format(ErrorMessages.UNKNOWN_USER, id));
            }

            var alg = Enum.GetName(typeof(OTPAlgs), _options.OTPAlg).ToLowerInvariant();
            var url = $"otpauth://{alg}/{_options.OTPIssuer}:{user.Id}?secret={user.OTPKey}&issuer={_options.OTPIssuer}";

            if (_options.OTPAlg == OTPAlgs.HOTP)
            {
                url = $"{url}&counter={user.OTPCounter}";
            }

            var qrGenerator = new QRCodeGenerator();
            var qrCodeData  = qrGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
            var qrCode      = new QRCode(qrCodeData);

            return(qrCode.GetGraphic(20));
        }
        public async Task <long> Handle(string id, string claimName, CancellationToken cancellationToken)
        {
            Domains.OAuthUser user;
            if (!string.IsNullOrWhiteSpace(claimName))
            {
                user = await _oauthUserRepository.FindOAuthUserByClaim(claimName, id, cancellationToken);
            }
            else
            {
                user = await _oauthUserRepository.FindOAuthUserByLogin(id, cancellationToken);
            }

            if (user == null)
            {
                _logger.LogError($"the user '{id}' doesn't exist");
                throw new OAuthUserNotFoundException(ErrorCodes.INVALID_REQUEST, string.Format(ErrorMessages.UNKNOWN_USER, id));
            }

            var authenticator = _otpAuthenticators.First(o => o.Alg == _options.OTPAlg);
            var otp           = authenticator.GenerateOtp(user);

            if (_options.OTPAlg == Domains.OTPAlgs.HOTP)
            {
                user.IncrementCounter();
                await _oauthUserRepository.Update(user, cancellationToken);

                await _oauthUserRepository.SaveChanges(cancellationToken);
            }

            _logger.LogInformation($"OTP {otp} has been generated");
            return(otp);
        }
示例#3
0
        public async Task <IActionResult> Index(ConfirmOpenBankingApiAccountConsentViewModel viewModel, CancellationToken cancellationToken)
        {
            try
            {
                await _mediator.Send(new ConfirmAccountAccessConsentCommand(viewModel.ConsentId, viewModel.SelectedAccounts), cancellationToken);

                var unprotectedUrl = _dataProtector.Unprotect(viewModel.ReturnUrl);
                var query          = unprotectedUrl.GetQueries().ToJObj();
                var claimName      = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
                var user           = await _oauthUserRepository.FindOAuthUserByLogin(claimName.Value, cancellationToken);

                var consent = _userConsentFetcher.FetchFromAuthorizationRequest(user, query);
                if (consent == null)
                {
                    consent = _userConsentFetcher.BuildFromAuthorizationRequest(query);
                    user.Consents.Add(consent);
                    await _oauthUserRepository.Update(user, cancellationToken);

                    await _oauthUserRepository.SaveChanges(cancellationToken);
                }

                return(Redirect(unprotectedUrl));
            }
            catch (CryptographicException)
            {
                ModelState.AddModelError("invalid_request", "invalid_request");
                return(View(viewModel));
            }
        }
示例#4
0
        public async Task <IActionResult> Manage(CancellationToken cancellationToken)
        {
            var nameIdentifier = GetNameIdentifier();
            var user           = await _oauthUserRepository.FindOAuthUserByLogin(nameIdentifier, cancellationToken);

            var result       = new List <ConsentViewModel>();
            var oauthClients = await _oauthClientRepository.FindOAuthClientByIds(user.Consents.Select(c => c.ClientId), cancellationToken);

            foreach (var consent in user.Consents)
            {
                var oauthClient = oauthClients.Single(c => c.ClientId == consent.ClientId);
                result.Add(new ConsentViewModel(
                               consent.Id,
                               _translationHelper.Translate(oauthClient.ClientNames, oauthClient.ClientId),
                               consent.Scopes.Select(s => s.Name),
                               consent.Claims));
            }

            return(View(result));
        }
示例#5
0
        public async Task <bool> Notify(BCAuthorize bcAuthorize, CancellationToken cancellationToken)
        {
            try
            {
                var handler = new HttpClientHandler
                {
                    AllowAutoRedirect = false
                };
                using (var httpClient = _httpClientFactory.GetHttpClient(handler))
                {
                    var jObjBody = new JObject();
                    var context  = new HandlerContext(new HandlerContextRequest(null, null, jObjBody, null, null, null));
                    var user     = await _oauthUserRepository.FindOAuthUserByLogin(bcAuthorize.UserId, cancellationToken);

                    var oauthClient = await _oauthClientRepository.FindOAuthClientById(bcAuthorize.ClientId, cancellationToken);

                    context.SetUser(user);
                    context.SetClient(oauthClient);
                    foreach (var tokenBuilder in _tokenBuilders)
                    {
                        await tokenBuilder.Build(bcAuthorize.Scopes, context, cancellationToken);
                    }

                    var content = new JObject
                    {
                        { BCAuthenticationResponseParameters.AuthReqId, bcAuthorize.Id }
                    };
                    foreach (var resp in context.Response.Parameters)
                    {
                        content.Add(resp.Key, resp.Value);
                    }

                    var httpRequestMessage = new HttpRequestMessage
                    {
                        RequestUri = new Uri(bcAuthorize.NotificationEdp),
                        Content    = new StringContent(content.ToString(), Encoding.UTF8, "application/json")
                    };
                    httpRequestMessage.Headers.Add("Authorization", bcAuthorize.NotificationToken);
                    var httpResult = await httpClient.SendAsync(httpRequestMessage, cancellationToken);

                    httpResult.EnsureSuccessStatusCode();
                    return(true);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return(false);
            }
        }
示例#6
0
        public async Task Refresh(JObject previousQueryParameters, HandlerContext currentContext, CancellationToken token)
        {
            if (!previousQueryParameters.ContainsKey(UserClaims.Subject))
            {
                return;
            }

            var scopes = previousQueryParameters.GetScopes();

            currentContext.SetUser(await _oauthUserRepository.FindOAuthUserByLogin(previousQueryParameters[UserClaims.Subject].ToString(), token));
            var openidClient = (OpenIdClient)currentContext.Client;
            var payload      = await BuildIdToken(currentContext, previousQueryParameters, scopes, token);

            var idToken = await _jwtBuilder.BuildClientToken(currentContext.Client, payload, openidClient.IdTokenSignedResponseAlg, openidClient.IdTokenEncryptedResponseAlg, openidClient.IdTokenEncryptedResponseEnc, token);

            currentContext.Response.Add(Name, idToken);
        }
        protected async Task <AuthorizationResponse> BuildResponse(HandlerContext context, CancellationToken cancellationToken)
        {
            var requestedResponseTypes = context.Request.RequestData.GetResponseTypesFromAuthorizationRequest();

            if (!requestedResponseTypes.Any())
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(ErrorMessages.MISSING_PARAMETER, AuthorizationRequestParameters.ResponseType));
            }

            var responseTypeHandlers    = _responseTypeHandlers.Where(r => requestedResponseTypes.Contains(r.ResponseType));
            var unsupportedResponseType = requestedResponseTypes.Where(r => !_responseTypeHandlers.Any(rh => rh.ResponseType == r));

            if (unsupportedResponseType.Any())
            {
                throw new OAuthException(ErrorCodes.UNSUPPORTED_RESPONSE_TYPE, string.Format(ErrorMessages.MISSING_RESPONSE_TYPES, string.Join(" ", unsupportedResponseType)));
            }

            context.SetClient(await AuthenticateClient(context.Request.RequestData, cancellationToken));
            context.SetUser(await _oauthUserRepository.FindOAuthUserByLogin(context.Request.UserSubject, cancellationToken));
            foreach (var validator in _authorizationRequestValidators)
            {
                await validator.Validate(context, cancellationToken);
            }

            var state       = context.Request.RequestData.GetStateFromAuthorizationRequest();
            var redirectUri = context.Request.RequestData.GetRedirectUriFromAuthorizationRequest();

            if (!string.IsNullOrWhiteSpace(state))
            {
                context.Response.Add(AuthorizationResponseParameters.State, state);
            }

            _authorizationRequestEnricher.Enrich(context);
            if (!context.Client.RedirectionUrls.Contains(redirectUri))
            {
                redirectUri = context.Client.RedirectionUrls.First();
            }

            foreach (var responseTypeHandler in responseTypeHandlers)
            {
                await responseTypeHandler.Enrich(context, cancellationToken);
            }

            _tokenProfiles.First(t => t.Profile == context.Client.PreferredTokenProfile).Enrich(context);
            return(new RedirectURLAuthorizationResponse(redirectUri, context.Response.Parameters));
        }
        public virtual async Task <OAuthUser> Authenticate(string login, string password, CancellationToken token)
        {
            var user = await _oauthUserRepository.FindOAuthUserByLogin(login, token);

            if (user == null)
            {
                throw new BaseUIException(Exceptions.ErrorCodes.UNKNOWN_USER);
            }

            var credential = user.Credentials.FirstOrDefault(c => c.CredentialType == Constants.AMR);
            var hash       = PasswordHelper.ComputeHash(password);

            if (credential == null || credential.Value != PasswordHelper.ComputeHash(password))
            {
                throw new BaseUIException(Exceptions.ErrorCodes.INVALID_CREDENTIALS);
            }

            return(user);
        }
        public override async Task <IActionResult> Handle(HandlerContext context, CancellationToken cancellationToken)
        {
            try
            {
                var oauthClient = await AuthenticateClient(context, cancellationToken);

                context.SetClient(oauthClient);
                var authRequest = await _cibaGrantTypeValidator.Validate(context, cancellationToken);

                var user = await _oauthUserRepository.FindOAuthUserByLogin(authRequest.UserId, cancellationToken);

                context.SetUser(user);
                foreach (var tokenBuilder in _tokenBuilders)
                {
                    await tokenBuilder.Build(authRequest.Scopes, context, cancellationToken);
                }

                _tokenProfiles.First(t => t.Profile == context.Client.PreferredTokenProfile).Enrich(context);
                var result = BuildResult(context, authRequest.Scopes);
                foreach (var kvp in context.Response.Parameters)
                {
                    result.Add(kvp.Key, kvp.Value);
                }

                authRequest.Send();
                await _bcAuthorizeRepository.Update(authRequest, cancellationToken);

                await _bcAuthorizeRepository.SaveChanges(cancellationToken);

                return(new OkObjectResult(result));
            }
            catch (OAuthUnauthorizedException ex)
            {
                return(BuildError(HttpStatusCode.Unauthorized, ex.Code, ex.Message));
            }
            catch (OAuthException ex)
            {
                _logger.LogError(ex.ToString());
                return(BuildError(HttpStatusCode.BadRequest, ex.Code, ex.Message));
            }
        }
        private async Task <IActionResult> Common(JObject content, CancellationToken cancellationToken)
        {
            try
            {
                var accessToken = ExtractAccessToken(content);
                var jwsPayload  = await Extract(accessToken, cancellationToken);

                if (jwsPayload == null)
                {
                    throw new OAuthException(ErrorCodes.INVALID_TOKEN, OAuth.ErrorMessages.BAD_TOKEN);
                }

                var subject   = jwsPayload.GetSub();
                var scopes    = jwsPayload.GetScopes();
                var audiences = jwsPayload.GetAudiences();
                var claims    = jwsPayload.GetClaimsFromAccessToken(AuthorizationRequestClaimTypes.UserInfo);
                var authTime  = jwsPayload.GetAuthTime();
                var user      = await _oauthUserRepository.FindOAuthUserByLogin(subject, cancellationToken);

                if (user == null)
                {
                    return(new UnauthorizedResult());
                }

                var filteredClients = await _oauthClientRepository.FindOAuthClientByIds(audiences, cancellationToken);

                if (!filteredClients.Any())
                {
                    throw new OAuthException(ErrorCodes.INVALID_CLIENT, ErrorMessages.INVALID_AUDIENCE);
                }

                var oauthClient = (OpenIdClient)filteredClients.First();
                if (!user.HasOpenIDConsent(oauthClient.ClientId, scopes, claims, AuthorizationRequestClaimTypes.UserInfo))
                {
                    throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.NO_CONSENT);
                }

                var token = await _tokenRepository.Get(accessToken, cancellationToken);

                if (token == null)
                {
                    _logger.LogError("Cannot get user information because access token has been rejected");
                    throw new OAuthException(ErrorCodes.INVALID_TOKEN, OAuth.ErrorMessages.ACCESS_TOKEN_REJECTED);
                }

                var oauthScopes = await _oauthScopeRepository.FindOAuthScopesByNames(scopes, cancellationToken);

                var payload = new JwsPayload();
                IdTokenBuilder.EnrichWithScopeParameter(payload, oauthScopes, user, subject);
                _claimsJwsPayloadEnricher.EnrichWithClaimsParameter(payload, claims, user, authTime, AuthorizationRequestClaimTypes.UserInfo);
                foreach (var claimsSource in _claimsSources)
                {
                    await claimsSource.Enrich(payload, oauthClient, cancellationToken);
                }

                string contentType = "application/json";
                var    result      = JsonConvert.SerializeObject(payload).ToString();
                if (!string.IsNullOrWhiteSpace(oauthClient.UserInfoSignedResponseAlg))
                {
                    payload.Add(Jwt.Constants.OAuthClaims.Issuer, Request.GetAbsoluteUriWithVirtualPath());
                    payload.Add(Jwt.Constants.OAuthClaims.Audiences, new string[]
                    {
                        token.ClientId
                    });
                    result = await _jwtBuilder.BuildClientToken(oauthClient, payload, oauthClient.UserInfoSignedResponseAlg, oauthClient.UserInfoEncryptedResponseAlg, oauthClient.UserInfoEncryptedResponseEnc, cancellationToken);

                    contentType = "application/jwt";
                }

                return(new ContentResult
                {
                    Content = result,
                    ContentType = contentType
                });
            }
            catch (OAuthException ex)
            {
                var jObj = new JObject
                {
                    { ErrorResponseParameters.Error, ex.Code },
                    { ErrorResponseParameters.ErrorDescription, ex.Message }
                };
                return(new ContentResult
                {
                    Content = jObj.ToString(),
                    ContentType = "application/json",
                    StatusCode = (int)HttpStatusCode.BadRequest
                });
            }
        }