827 lines
28 KiB
C#
827 lines
28 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using IdentityModel;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.WebUtilities;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityService.Configuration;
|
|
using xIdentityService.Constants;
|
|
using xIdentityService.Interfaces;
|
|
using xIdentityService.Providers;
|
|
using xModels.Base;
|
|
|
|
namespace xIdentityService.Middlewares {
|
|
/// <summary>
|
|
/// Proxy Server Middleware ...
|
|
/// </summary>
|
|
public class XProxyMiddleware : XBaseClass {
|
|
//
|
|
#region Pros ...
|
|
private readonly HttpClient HTTP_CLIENT;
|
|
private readonly RequestDelegate NEXT_MIDDLEWARE;
|
|
private readonly XProxyConfiguration CONFIGURATION;
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XProxyMiddleware (
|
|
ILoggerFactory loggerFactory,
|
|
RequestDelegate nextMiddleware,
|
|
XProxyConfiguration configuration,
|
|
IHttpClientFactory httpClientFactory
|
|
) : base (loggerFactory) {
|
|
//
|
|
this.CONFIGURATION = configuration;
|
|
this.NEXT_MIDDLEWARE = nextMiddleware;
|
|
|
|
//
|
|
// Create Http Client ...
|
|
this.HTTP_CLIENT = httpClientFactory
|
|
.CreateClient (XProxyConstants.XPROXY_HTTP_CLIENT);
|
|
|
|
//
|
|
// Logging Server Configuration ...
|
|
LogXProxyServerConfig ();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Public ...
|
|
public async Task InvokeAsync (HttpContext context) {
|
|
//
|
|
#region Bussiness Logic ...
|
|
//
|
|
var routeDescriptor = GetRouteDescriptor (context.Request);
|
|
if (!routeDescriptor.IsNull ()) {
|
|
//
|
|
#region Handle Authorization ...
|
|
//
|
|
try {
|
|
//
|
|
// Handle XPowered ...
|
|
if (routeDescriptor.EnableXPoweredByAthorization) {
|
|
//
|
|
var isPoweredByPass = context.Request.Headers
|
|
.Any (h => h.Key
|
|
.ToNormalString () == xCommons.Constants.XAuthorization.XPoweredBy
|
|
.ToNormalString () &&
|
|
h.Value
|
|
.ToString ()
|
|
.ToNormalString () == CONFIGURATION.XPoweredValue
|
|
.ToNormalString ()
|
|
);
|
|
|
|
//
|
|
if (!isPoweredByPass) {
|
|
ThrowNotAuthorizedException ();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Handle EndableAuthorization ...
|
|
if (routeDescriptor.EnableAuthorization) {
|
|
//
|
|
// Retrieve User Info for Authentication ...
|
|
var userName = context.User.Identity.Name;
|
|
var isUserAuthenticated = !userName.IsNull () &&
|
|
context.User.Identity.IsAuthenticated;
|
|
if (!isUserAuthenticated &&
|
|
!routeDescriptor.AllowedScopes.HasChild ()
|
|
) {
|
|
ThrowNotAuthorizedException ();
|
|
}
|
|
|
|
//
|
|
// Check Allowed Scopes Authorization ...
|
|
if (routeDescriptor.AllowedScopes.HasChild ()) {
|
|
//
|
|
var scopeClaims = context.User.Claims
|
|
.Where (c => c.Type == JwtClaimTypes.Scope)
|
|
.Select (c => c.Value);
|
|
var isScopePassed = scopeClaims.HasChild () &&
|
|
scopeClaims.Any (c => routeDescriptor.AllowedScopes
|
|
.Any (allowedScope => allowedScope
|
|
.ToNormalString () == c
|
|
.ToNormalString ()
|
|
)
|
|
);
|
|
if (!isScopePassed) {
|
|
ThrowNotAuthorizedException ();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Allowed Roles Authorization ...
|
|
if (
|
|
isUserAuthenticated &&
|
|
routeDescriptor.AllowedRoles.HasChild ()
|
|
) {
|
|
//
|
|
var roleClaim = context.User.Claims
|
|
.FirstOrDefault (c => c.Type == JwtClaimTypes.Role);
|
|
var isRolePassed = !roleClaim.IsNull () &&
|
|
routeDescriptor.AllowedRoles
|
|
.Any (role => role
|
|
.ToNormalString () == roleClaim.Value
|
|
.ToNormalString ());
|
|
if (!isRolePassed) {
|
|
ThrowNotAuthorizedException ();
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
context.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
|
|
return;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
// Extract Request Uri from Received Request ...
|
|
var requestUri = GetUri (context.Request);
|
|
if (!requestUri.IsNull ()) {
|
|
//
|
|
// Retrieve Request based on current ...
|
|
var request = GetRequestMessage (
|
|
uri: requestUri,
|
|
context: context
|
|
);
|
|
|
|
//
|
|
SendLog ($"Send Request to Recieve Response ...", LogLevel.Information);
|
|
|
|
//
|
|
// Send Request and Retrieve Response ...
|
|
try {
|
|
//
|
|
var response = await HTTP_CLIENT.SendAsync (
|
|
request,
|
|
HttpCompletionOption.ResponseContentRead
|
|
);
|
|
|
|
//
|
|
// Set Current Response Status Code ...
|
|
context.Response.StatusCode = (int) response.StatusCode;
|
|
|
|
//
|
|
// Retrieve Response Headers and Set To Current Response ...
|
|
HandleResponseHeaders (context, response);
|
|
|
|
//
|
|
// Processing Response Content ...
|
|
await ProcessResponseContent (context, response);
|
|
} catch (Exception ex) {
|
|
//
|
|
LogMessage ($"Exception: {ex.Message}", LogLevel.Error);
|
|
|
|
//
|
|
context.Response.StatusCode = (int) HttpStatusCode.BadRequest;
|
|
}
|
|
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
await NEXT_MIDDLEWARE (context);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
/// <summary>
|
|
/// Throw Required Exception ...
|
|
/// </summary>
|
|
private void ThrowNotAuthorizedException () {
|
|
throw XException.NotAuthorized.ToException ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show propper logs if Enabled ...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <param name="logLevel"></param>
|
|
private void SendLog (string message, LogLevel logLevel = LogLevel.Information) {
|
|
//
|
|
if (!CONFIGURATION.EnableLogging) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
LogMessage (
|
|
message: message,
|
|
logLevel: logLevel
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Log Proxy Server Configuration ...
|
|
/// </summary>
|
|
private void LogXProxyServerConfig () {
|
|
//
|
|
// Retrieve XProxyConfiguration class from Configurations and Validate them ...
|
|
if (CONFIGURATION.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
// Try to Log Proxy Configuration ...
|
|
ConsoleMessage ("===============================");
|
|
ConsoleMessage ("= Proxy Server Configurations: ");
|
|
ConsoleMessage ("===============================");
|
|
|
|
//
|
|
ConsoleMessage ($"Host: {CONFIGURATION.Host}");
|
|
ConsoleMessage ($"XPoweredValue: {CONFIGURATION.XPoweredValue}");
|
|
ConsoleMessage ($"EnableLogging: {CONFIGURATION.EnableLogging}");
|
|
ConsoleMessage ($"DisableSSLCheck: {CONFIGURATION.DisableSSLCheck}");
|
|
ConsoleMessage ($"AllowAutoRedirect: {CONFIGURATION.AllowAutoRedirect}");
|
|
ConsoleMessage ($" ");
|
|
ConsoleMessage ($"Routes: ");
|
|
ConsoleMessage ($" ");
|
|
|
|
//
|
|
CONFIGURATION.Routes
|
|
.ToList ()
|
|
.ForEach (routeDescriptor => {
|
|
ConsoleMessage ("===============================");
|
|
ConsoleMessage ($"= Rote => {routeDescriptor.Route}");
|
|
ConsoleMessage ("===============================");
|
|
ConsoleMessage ($"AllowedRoles: {routeDescriptor.AllowedRoles.ToJSON()}");
|
|
ConsoleMessage ($"AllowedScopes: {routeDescriptor.AllowedScopes.ToJSON()}");
|
|
ConsoleMessage ($"EnableAuthorization: {routeDescriptor.EnableAuthorization}");
|
|
ConsoleMessage ($"EnableXPoweredByAthorization: {routeDescriptor.EnableXPoweredByAthorization}");
|
|
ConsoleMessage ($" ");
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Destination Request Path based on Current Request ...
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
private Uri GetUri (HttpRequest request) {
|
|
//
|
|
// Create temp result ...
|
|
Uri result = null;
|
|
var requestPath = "";
|
|
|
|
//
|
|
SendLog ($"Receive Request: {request.Path} ...", LogLevel.Information);
|
|
|
|
//
|
|
// Try to Findout Route Descriptor ...
|
|
var routeDescriptor = GetRouteDescriptor (request);
|
|
|
|
//
|
|
// Route Descriptor Exists && Path for Delegating ...
|
|
if (!routeDescriptor.IsNull () &&
|
|
request.Path
|
|
.StartsWithSegments (routeDescriptor.Route)
|
|
) {
|
|
//
|
|
// Prepare Request Path by Cleaning Starter Path Segment ...
|
|
requestPath = request.Path
|
|
.ToString ()
|
|
.Replace (routeDescriptor.Route, "");
|
|
if (requestPath.StartsWith ("/")) {
|
|
requestPath = requestPath.Substring (1);
|
|
}
|
|
|
|
//
|
|
// Decoding URL ...
|
|
requestPath = HttpUtility.UrlDecode (requestPath);
|
|
|
|
//
|
|
var colonIndex = requestPath.IndexOf (":");
|
|
if (colonIndex > -1) {
|
|
//
|
|
var doubleSlash = requestPath.Substring (colonIndex + 1, 2);
|
|
var isDoubleSlash = doubleSlash == "//";
|
|
|
|
//
|
|
if (!isDoubleSlash) {
|
|
//
|
|
var protocol = requestPath
|
|
.Substring (0, colonIndex);
|
|
var section = requestPath
|
|
.Substring (colonIndex + 2, requestPath.Length - colonIndex - 2);
|
|
|
|
//
|
|
requestPath = $"{protocol}://{section}";
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Request Path ...
|
|
if (!requestPath.IsNullOrEmpty ()) {
|
|
//
|
|
result = new Uri (requestPath);
|
|
|
|
//
|
|
SendLog ($"Process Request: {requestPath} ...", LogLevel.Information);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Propper Request Message based on HttpContext and uri ...F
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="uri"></param>
|
|
/// <returns></returns>
|
|
private HttpRequestMessage GetRequestMessage (
|
|
HttpContext context,
|
|
Uri uri
|
|
) {
|
|
//
|
|
var result = new HttpRequestMessage ();
|
|
FillRequest (context, result);
|
|
|
|
//
|
|
// Handle Queries ...
|
|
SendLog ($"Start Processing Queries: ");
|
|
foreach (var query in context.Request.Query) {
|
|
//
|
|
var key = query.Key;
|
|
var value = HttpUtility.UrlDecode (query.Value);
|
|
|
|
//
|
|
uri = new Uri (
|
|
QueryHelpers.AddQueryString (
|
|
uri.OriginalString,
|
|
new Dictionary<string, string> {
|
|
[key] = value
|
|
}
|
|
)
|
|
);
|
|
|
|
//
|
|
SendLog ($"Query : {key}:{value} was Processed ...");
|
|
}
|
|
|
|
//
|
|
result.RequestUri = uri;
|
|
result.Headers.Host = uri.Host;
|
|
|
|
//
|
|
// Retrieve Request Method ...
|
|
result.Method = GetMethod (context.Request.Method);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fill Request Message by provide HttpContext ...
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="message"></param>
|
|
private void FillRequest (
|
|
HttpContext context,
|
|
HttpRequestMessage message
|
|
) {
|
|
//
|
|
var requestMethod = context.Request.Method;
|
|
|
|
//
|
|
if (!HttpMethods.IsGet (requestMethod) &&
|
|
!HttpMethods.IsHead (requestMethod) &&
|
|
!HttpMethods.IsTrace (requestMethod) &&
|
|
!HttpMethods.IsDelete (requestMethod)
|
|
) {
|
|
//
|
|
var streamContent = new StreamContent (context.Request.Body);
|
|
message.Content = streamContent;
|
|
}
|
|
|
|
//
|
|
// Handle Base Headers ...
|
|
var regularHeaders = context.Request.Headers
|
|
.Where (hr => hr.Key != XProxyConstants.XPROXY_ACCEPTED_HEADERS &&
|
|
!hr.Key
|
|
.Contains (
|
|
XProxyConstants.XPROXY_FORWARD_HEADER
|
|
)
|
|
);
|
|
|
|
//
|
|
// Handle Aceepted Headers ...
|
|
IEnumerable<string> acceptedHeaders = null;
|
|
var acceptedHeadersKeyValue = context.Request.Headers
|
|
.FirstOrDefault (hr =>
|
|
hr.Key == XProxyConstants.XPROXY_ACCEPTED_HEADERS
|
|
);
|
|
if (!acceptedHeadersKeyValue.IsNull ()) {
|
|
//
|
|
acceptedHeaders = acceptedHeadersKeyValue.Value
|
|
.ToString ()
|
|
.ParseListString<string> ();
|
|
|
|
//
|
|
// Filter Regular Headers ...
|
|
if (
|
|
regularHeaders.HasChild () &&
|
|
acceptedHeaders.HasChild ()
|
|
) {
|
|
//
|
|
regularHeaders = regularHeaders
|
|
.Where (rhr => acceptedHeaders
|
|
.Contains (rhr.Key)
|
|
);
|
|
}
|
|
}
|
|
foreach (var header in regularHeaders) {
|
|
//
|
|
SendLog ($"Adding Header: {header.Key}:{header.Value} ...");
|
|
|
|
//
|
|
message.Headers.Add (
|
|
header.Key,
|
|
header.Value
|
|
.ToString ()
|
|
);
|
|
}
|
|
|
|
//
|
|
// Handle ForWarded Headers ...
|
|
// Since Forward Headers is Custom kind, this means user actually need this
|
|
// Header, so there is no need to put them on AcceptedHeaders ...
|
|
var forwardHeaders = context.Request.Headers
|
|
.Where (hr => hr.Key
|
|
.Contains (
|
|
XProxyConstants.XPROXY_FORWARD_HEADER
|
|
)
|
|
);
|
|
foreach (var header in forwardHeaders) {
|
|
//
|
|
var key = header.Key
|
|
.Replace (
|
|
XProxyConstants.XPROXY_FORWARD_HEADER,
|
|
string.Empty
|
|
);
|
|
|
|
//
|
|
SendLog ($"Forwarding Header: {header.Key} to {key} ...");
|
|
|
|
//
|
|
message.Headers
|
|
.Add (
|
|
key,
|
|
header.Value
|
|
.ToString ()
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retreive and Extract Method Type of HttpRequest ...
|
|
/// </summary>
|
|
/// <param name="method"></param>
|
|
/// <returns></returns>
|
|
private static HttpMethod GetMethod (string method) {
|
|
//
|
|
if (HttpMethods.IsDelete (method)) {
|
|
return HttpMethod.Delete;
|
|
} else if (HttpMethods.IsGet (method)) {
|
|
return HttpMethod.Get;
|
|
} else if (HttpMethods.IsHead (method)) {
|
|
return HttpMethod.Head;
|
|
} else if (HttpMethods.IsOptions (method)) {
|
|
return HttpMethod.Options;
|
|
} else if (HttpMethods.IsPost (method)) {
|
|
return HttpMethod.Post;
|
|
} else if (HttpMethods.IsPut (method)) {
|
|
return HttpMethod.Put;
|
|
} else if (HttpMethods.IsTrace (method)) {
|
|
return HttpMethod.Trace;
|
|
}
|
|
|
|
//
|
|
return new HttpMethod (method);
|
|
}
|
|
|
|
/// <summary>
|
|
/// add all headers exists in HttpResponse MEssage to Current Context Response Headers ...
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="message"></param>
|
|
private void HandleResponseHeaders (
|
|
HttpContext context,
|
|
HttpResponseMessage message
|
|
) {
|
|
//
|
|
// Handle Message Headers ...
|
|
foreach (var header in message.Headers) {
|
|
context.Response.Headers[header.Key] = header.Value
|
|
.ToArray ();
|
|
}
|
|
|
|
//
|
|
// Handle Message Content Headers ...
|
|
foreach (var header in message.Content.Headers) {
|
|
context.Response.Headers[header.Key] = header.Value
|
|
.ToArray ();
|
|
}
|
|
|
|
//
|
|
context.Response.Headers.Remove ("transfer-encoding");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processing Response Content and Handle it on HttpContextResponse ...
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
private async Task ProcessResponseContent (
|
|
HttpContext context,
|
|
HttpResponseMessage message
|
|
) {
|
|
//
|
|
// Reading Content as Byte Array ...
|
|
var contentBytes = await message.Content
|
|
.ReadAsByteArrayAsync ();
|
|
|
|
//
|
|
// Check ContentType of Response ...
|
|
if (
|
|
IsContentOfType (message, XResponseContentTypes.HTML) ||
|
|
IsContentOfType (message, XResponseContentTypes.JSON) ||
|
|
IsContentOfType (message, XResponseContentTypes.JavaScript)
|
|
) {
|
|
//
|
|
// If their String Content ...
|
|
var stringContent = Encoding.UTF8.GetString (contentBytes);
|
|
|
|
//
|
|
// TODO: here we can change String Contents ...
|
|
|
|
//
|
|
// Writing new Content to Response ...
|
|
await context.Response
|
|
.WriteAsync (
|
|
stringContent,
|
|
Encoding.UTF8
|
|
);
|
|
} else {
|
|
//
|
|
// if they have non string content ...
|
|
await context.Response.Body
|
|
.WriteAsync (
|
|
buffer: contentBytes,
|
|
offset: 0,
|
|
count: contentBytes.Length
|
|
);
|
|
}
|
|
|
|
//
|
|
SendLog ($"Response Content Processed ...", LogLevel.Information);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Content Type of Specific Response ...
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
private bool IsContentOfType (
|
|
HttpResponseMessage response,
|
|
string type
|
|
) {
|
|
//
|
|
// Create EMpty Result ...
|
|
var result = false;
|
|
|
|
//
|
|
// Retrieve and Check Content Type of Response ...
|
|
if (response.Content?.Headers?.ContentType != null) {
|
|
result = response.Content.Headers.ContentType.MediaType == type;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve and Extract Route Descriptor ...
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
private XProxyRouteDescriptor GetRouteDescriptor (HttpRequest request) {
|
|
//
|
|
// Validate Args ...
|
|
if (
|
|
CONFIGURATION.IsNull () ||
|
|
!CONFIGURATION.Routes.HasChild ()
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = CONFIGURATION.Routes
|
|
.FirstOrDefault (rd => !rd.Route.IsNullOrEmpty () &&
|
|
request.Path
|
|
.StartsWithSegments (rd.Route
|
|
.ToNormalString ()
|
|
)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Provide all requirements for Dependency Injection Handler ...
|
|
/// </summary>
|
|
public static class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Retrieve XProxy Middelware Configuration from Configuration ...
|
|
/// </summary>
|
|
/// <param name="config"></param>
|
|
/// <returns></returns>
|
|
public static XProxyConfiguration GetXProxyConfiguration (this IConfiguration config) {
|
|
//
|
|
var xProxyConfiguration = config.GetSection (ConfigurationNodeNames.XPROXY_CONFIGURATION_NODE_NAME);
|
|
return xProxyConfiguration.Get<XProxyConfiguration> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register HTTP Handler for XProxy Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="httpHandler"></param>
|
|
public static void AddXProxyHttpHandler (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
HttpClientHandler httpHandler = null
|
|
) {
|
|
//
|
|
var proxyConfig = configuration.GetXProxyConfiguration ();
|
|
if (proxyConfig.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
services.AddXProxyHttpHandler (
|
|
httpHandler: httpHandler,
|
|
configuration: proxyConfig
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register HTTP Handler for XProxy Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="httpHandler"></param>
|
|
public static void AddXProxyHttpHandler (
|
|
this IServiceCollection services,
|
|
XProxyConfiguration configuration,
|
|
HttpClientHandler httpHandler = null
|
|
) {
|
|
//
|
|
if (configuration.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
if (httpHandler.IsNull ()) {
|
|
httpHandler = new HttpClientHandler ();
|
|
}
|
|
|
|
//
|
|
httpHandler.AllowAutoRedirect = configuration.AllowAutoRedirect;
|
|
|
|
//
|
|
if (configuration.DisableSSLCheck) {
|
|
httpHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
|
|
}
|
|
|
|
//
|
|
services
|
|
.AddHttpClient (XProxyConstants.XPROXY_HTTP_CLIENT)
|
|
.ConfigurePrimaryHttpMessageHandler (() => {
|
|
return httpHandler;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XProxy On Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="httpHandler"></param>
|
|
public static void AddXProxyServer (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration,
|
|
HttpClientHandler httpHandler = null
|
|
) {
|
|
//
|
|
var proxyConfig = configuration.GetXProxyConfiguration ();
|
|
|
|
//
|
|
services.AddXProxyServer (
|
|
httpHandler: httpHandler,
|
|
configuration: proxyConfig
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XProxy On Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="httpHandler"></param>
|
|
public static void AddXProxyServer (
|
|
this IServiceCollection services,
|
|
XProxyConfiguration configuration,
|
|
HttpClientHandler httpHandler = null
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (configuration.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
// Register Proxy Configuration ...
|
|
services.AddSingleton<XProxyConfiguration> (configuration);
|
|
|
|
//
|
|
// Regiter Proxy Handler ...
|
|
services.AddXProxyHttpHandler (
|
|
httpHandler: httpHandler,
|
|
configuration: configuration
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XProxy On Server ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXProxyClient (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
var proxyConfig = configuration.GetXProxyConfiguration ();
|
|
|
|
//
|
|
services.AddXProxyClient (
|
|
configuration: proxyConfig
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XProxy On Client ...
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXProxyClient (
|
|
this IServiceCollection services,
|
|
XProxyConfiguration configuration
|
|
) {
|
|
//
|
|
// Validate Args ...
|
|
if (configuration.IsNull ()) {
|
|
throw XException.InvalidConfiguration.ToException ();
|
|
}
|
|
|
|
//
|
|
// Register Proxy Configuration ...
|
|
services.AddSingleton<XProxyConfiguration> (configuration);
|
|
|
|
//
|
|
// Register IXProxyHelper ...
|
|
services.AddSingleton<IXProxyHelper, XProxyHelper> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adding XProxy Middleware to Applications ...
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public static void UseXProxy (this IApplicationBuilder app) {
|
|
app.UseMiddleware<XProxyMiddleware> ();
|
|
}
|
|
}
|
|
} |