public async Task <IActionResult> Create(HandlerContext context, CancellationToken cancellationToken)
        {
            try
            {
                var oauthClient = await _clientAuthenticationHelper.AuthenticateClient(context.Request.HttpHeader, context.Request.RequestData, context.Request.Certificate, context.Request.IssuerName, cancellationToken, ErrorCodes.INVALID_REQUEST);

                context.SetClient(oauthClient);
                var user = await _bcAuthorizeRequestValidator.ValidateCreate(context, cancellationToken);

                context.SetUser(user);
                var requestedExpiry = context.Request.RequestData.GetRequestedExpiry();
                var interval        = context.Request.RequestData.GetInterval();
                if (requestedExpiry == null)
                {
                    requestedExpiry = _options.AuthRequestExpirationTimeInSeconds;
                }

                var currentDateTime = DateTime.UtcNow;
                var openidClient    = oauthClient as OpenIdClient;
                var permissions     = await GetPermissions(context.Client.ClientId, context.User.Id, cancellationToken);

                var bcAuthorize = Domains.BCAuthorize.Create(
                    currentDateTime.AddSeconds(requestedExpiry.Value),
                    oauthClient.ClientId,
                    interval ?? _options.DefaultBCAuthorizeWaitIntervalInSeconds,
                    openidClient.BCClientNotificationEndpoint,
                    openidClient.BCTokenDeliveryMode,
                    context.Request.RequestData.GetScopesFromAuthorizationRequest(),
                    context.User.Id,
                    context.Request.RequestData.GetClientNotificationToken(),
                    permissions);
                bcAuthorize.IncrementNextFetchTime();
                await _bcAuthorizeRepository.Add(bcAuthorize, cancellationToken);

                await _bcAuthorizeRepository.SaveChanges(cancellationToken);

                foreach (var grp in permissions.GroupBy(p => p.ConsentId))
                {
                    await _bcNotificationService.Notify(context, bcAuthorize.Id, grp.ToArray(), cancellationToken);
                }

                return(new OkObjectResult(new JObject
                {
                    { BCAuthenticationResponseParameters.AuthReqId, bcAuthorize.Id },
                    { BCAuthenticationResponseParameters.ExpiresIn, requestedExpiry.Value }
                }));
            }
            catch (OAuthUnauthorizedException ex)
            {
                return(BaseCredentialsHandler.BuildError(HttpStatusCode.Unauthorized, ex.Code, ex.Message));
            }
            catch (OAuthException ex)
            {
                return(BaseCredentialsHandler.BuildError(HttpStatusCode.BadRequest, ex.Code, ex.Message));
            }
        }
예제 #2
0
        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));
            }
        }
예제 #3
0
        public async Task <Domains.BCAuthorize> Validate(HandlerContext context, CancellationToken cancellationToken)
        {
            var openidClient = context.Client as OpenIdClient;

            if (openidClient.BCTokenDeliveryMode != SIDOpenIdConstants.StandardNotificationModes.Ping &&
                openidClient.BCTokenDeliveryMode != SIDOpenIdConstants.StandardNotificationModes.Poll)
            {
                throw new OAuthException(OAuth.ErrorCodes.INVALID_REQUEST, ErrorMessages.ONLY_PINGORPUSH_MODE_CAN_BE_USED);
            }

            var authRequestId = context.Request.RequestData.GetAuthRequestId();

            if (string.IsNullOrWhiteSpace(authRequestId))
            {
                throw new OAuthException(OAuth.ErrorCodes.INVALID_REQUEST, string.Format(OAuth.ErrorMessages.MISSING_PARAMETER, AuthorizationRequestParameters.AuthReqId));
            }

            var authRequest = await _bcAuthorizeRepository.Get(authRequestId, cancellationToken);

            if (authRequest == null)
            {
                throw new OAuthException(OAuth.ErrorCodes.INVALID_GRANT, ErrorMessages.INVALID_AUTH_REQUEST_ID);
            }

            if (authRequest.ClientId != openidClient.ClientId)
            {
                throw new OAuthException(OAuth.ErrorCodes.INVALID_GRANT, ErrorMessages.AUTH_REQUEST_CLIENT_NOT_AUTHORIZED);
            }

            var currentDateTime = DateTime.UtcNow;
            var isSlowDown      = currentDateTime <= authRequest.NextFetchTime;

            if (authRequest.Status == Domains.BCAuthorizeStatus.Pending || isSlowDown)
            {
                if (isSlowDown)
                {
                    throw new OAuthException(OAuth.ErrorCodes.SLOW_DOWN, string.Format(ErrorMessages.TOO_MANY_AUTH_REQUEST, authRequestId));
                }

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

                await _bcAuthorizeRepository.SaveChanges(cancellationToken);

                throw new OAuthException(OAuth.ErrorCodes.AUTHORIZATION_PENDING, string.Format(ErrorMessages.AUTH_REQUEST_NOT_CONFIRMED, authRequestId));
            }

            if (authRequest.Status == BCAuthorizeStatus.Rejected)
            {
                throw new OAuthException(OAuth.ErrorCodes.ACCESS_DENIED, string.Format(ErrorMessages.AUTH_REQUEST_REJECTED, authRequestId));
            }

            if (authRequest.Status == BCAuthorizeStatus.Sent)
            {
                throw new OAuthException(OAuth.ErrorCodes.INVALID_GRANT, string.Format(ErrorMessages.AUTH_REQUEST_SENT, authRequestId));
            }

            if (currentDateTime > authRequest.ExpirationDateTime)
            {
                throw new OAuthException(OAuth.ErrorCodes.EXPIRED_TOKEN, string.Format(ErrorMessages.AUTH_REQUEST_EXPIRED, authRequestId));
            }

            return(authRequest);
        }