예제 #1
0
 private void SetForbiddenResponse(Ianvs::IanvsContext ianvsContext)
 {
     // Client not authorized
     // Return 403 - Forbidden (https://tools.ietf.org/html/rfc7231#section-6.5.3)
     ianvsContext.StatusCode = 403;
     ianvsContext.Response   = "";
 }
예제 #2
0
 private void SetUnAuthorizedResponse(Ianvs::IanvsContext ianvsContext)
 {
     // Client not authenticated
     // Return 401 - Unauthorized (https://tools.ietf.org/html/rfc7235#section-3.1)
     ianvsContext.StatusCode = 401;
     ianvsContext.Response   = "";
     // TODO: Add WWW-Authenticate header
 }
예제 #3
0
        public async Task InvokeAsync(HttpContext httpContext, Ianvs::IanvsContext ianvsContext,
                                      IIanvsConfigurationStore ianvsConfiguration, AuthenticatorFactory authenticatorFactory)
        {
            // TODO: Implement Security
            // https://github.com/onyx-ws/ianvs/issues/8

            // Any security requirements?
            ianvsContext.Security = GetSecurityRequirements(ianvsContext);
            // Yes
            if (ianvsContext.Security?.Count > 0)
            {
                _logger.LogInformation($"{Environment.MachineName} {ianvsContext.RequestId} Authenticating request");
                AuthenticationResult authResult = await Authenticate(httpContext, ianvsContext, ianvsConfiguration, authenticatorFactory);

                if (!authResult.Authenticated)
                {
                    _logger.LogWarning($"{Environment.MachineName} {ianvsContext.RequestId} Request authentication failed");
                    _logger.LogWarning($"{Environment.MachineName} {ianvsContext.RequestId} Authentication Error: {authResult.Error}");
                    SetUnAuthorizedResponse(ianvsContext);
                    return;
                }
                else
                {
                    _logger.LogInformation($"{Environment.MachineName} {ianvsContext.RequestId} Request authenticated successfully");
                    ianvsContext.Principal = authResult.Principal;

                    _logger.LogInformation($"{Environment.MachineName} {ianvsContext.RequestId} Authorizing request");
                    authResult = await Authorize(httpContext, ianvsContext);

                    if (!authResult.Authenticated)
                    {
                        _logger.LogWarning($"{Environment.MachineName} {ianvsContext.RequestId} Request authorization failed");
                        _logger.LogWarning($"{Environment.MachineName} {ianvsContext.RequestId} Authorization Error: {authResult.Error}");
                        SetForbiddenResponse(ianvsContext);
                        return;
                    }
                    else
                    {
                        _logger.LogInformation($"{Environment.MachineName} {ianvsContext.RequestId} Request authorized successfully");
                    }
                }
            }
            // request authenticated or no security requirement
            await _next(httpContext);
        }
예제 #4
0
        public async Task InvokeAsync(HttpContext httpContext, Ianvs::IanvsContext ianvsContext,
                                      IIanvsConfigurationStore ianvsConfiguration, Tracer tracer)
        {
            // TODO: Implement Routing
            // WIP - https://github.com/onyx-ws/ianvs/issues/1
            // TODO: Handle endpoints with templates
            // https://github.com/onyx-ws/ianvs/issues/2

            var routingSpan = tracer.StartSpan("ianvs-routing");

            // Find a matching Path
            string requestPath = httpContext.Request.Path;

            _logger.LogInformation($"{Environment.MachineName} {ianvsContext.RequestId} Looking for a configured route");
            Ianvs::Endpoint matchedEndpoint = ianvsConfiguration.Endpoints.FirstOrDefault(
                endpoint =>
                requestPath == (!string.IsNullOrWhiteSpace(endpoint.IanvsUrl) ? endpoint.IanvsUrl : endpoint.Url)
                );

            if (matchedEndpoint is null)
            {
                // Path not found
                // Return 404 - Not Found (https://tools.ietf.org/html/rfc7231#section-6.5.4)
                routingSpan.AddEvent("Route not matched");
                _logger.LogWarning($"{Environment.MachineName} {ianvsContext.RequestId} No configured route found");
                ianvsContext.StatusCode = 404;
                ianvsContext.Response   = "";
            }
            else
            {
                ianvsContext.MatchedEndpoint = matchedEndpoint;
                _logger.LogInformation($"{Environment.MachineName} {ianvsContext.RequestId} Possible matching route found at {ianvsContext.MatchedEndpoint.Url}");

                // Path found - Match Operation
                string           requestMethod    = httpContext.Request.Method;
                Ianvs::Operation matchedOperation = matchedEndpoint.Operations.FirstOrDefault(
                    operation =>
                    operation.Method.Equals(requestMethod, StringComparison.InvariantCultureIgnoreCase)
                    );
                if (matchedOperation is null)
                {
                    // Operation not found
                    // Return 405 - Method Not Allowed (https://tools.ietf.org/html/rfc7231#section-6.5.5)
                    routingSpan.AddEvent("Method not matched");
                    _logger.LogWarning($"{Environment.MachineName} {ianvsContext.RequestId} No configured operation found");
                    ianvsContext.StatusCode = 405;
                    ianvsContext.Response   = "";
                }
                else
                {
                    // Operation found
                    // Simulate operation
                    routingSpan.AddEvent("Route found");

                    ianvsContext.MatchedOperation = matchedOperation;
                    _logger.LogInformation($"{Environment.MachineName} {ianvsContext.RequestId} Matched route at {ianvsContext.MatchedOperation.OperationId} {ianvsContext.MatchedOperation.Method} {ianvsContext.MatchedEndpoint.Url}");

                    await _next(httpContext);
                }
            }

            routingSpan.End();
        }