### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Configuration\XIdentityServiceConfiguration.cs
using xIdentityService.Constants;
namespace xIdentityService.Configuration {
public partial class XIdentityServiceConfiguration {
public string Authority { get; set; }
public string ApiName { get; set; }
public string ApiSecret { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string XPoweredValue { get; set; }
public XTokenType TokenType { get; set; }
public string XRevisionSecretKey { get; set; }
public int DefaultClientTimeout { get; set; } = 360;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Configuration\XProxyConfiguration.cs
using System.Collections.Generic;
using xModels.Base;
namespace xIdentityService.Configuration {
///
/// XProxy Middleware Configuration ...
///
public class XProxyConfiguration {
///
/// Proxy Host Address for Clients Which Use XProxy Server ...
///
///
public string Host { get; set; }
///
/// if EnableXPoweredByAthorization property setted to true, this property determines
/// the header must be this value ...
///
///
public string XPoweredValue { get; set; }
///
/// Determines Proxy Http Handler Check SSL or not ...
///
///
public bool DisableSSLCheck { get; set; }
///
/// Determines Http Client Handler Allow Auto Redirect or not ...
///
///
public bool AllowAutoRedirect { get; set; }
///
/// Determines Proxy Server Log Received Requests or not ...
///
///
public bool EnableLogging { get; set; }
///
/// DefineRoutes for Handling ...
///
///
public HashSet Routes { get; set; }
}
///
/// Describe a Proxy Route ...
///
public class XProxyRouteDescriptor : XBaseDescriptor {
///
/// Determines which route can handled for Proxyfing ...
///
///
public string Route { get; set; }
///
/// Determines Proxy Server Handle Athorization or not ...
///
///
public bool EnableAuthorization { get; set; }
///
/// Determines Which Scopes allowed to this route if authorizations enabled ...
///
///
public HashSet AllowedScopes { get; set; }
///
/// Determines Which Roles allowed to this route if authorizations enabled ...
///
///
public HashSet AllowedRoles { get; set; }
///
/// Determines XProxy Can Check XPowered By Authorization or not ...
///
///
public bool EnableXPoweredByAthorization { get; set; }
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\ConfigurationNodeNames.cs
namespace xIdentityService.Constants {
public partial struct ConfigurationNodeNames {
public const string XPROXY_CONFIGURATION_NODE_NAME = "ProxyConfiguration";
public const string IDENTITY_SERVICE_NODE_NAME = "IdentityServiceConfiguration";
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XApiAccountEndpoint.cs
using xExceptions.Attributes;
namespace xIdentityService.Constants
{
public enum XApiAccountEndpoint
{
//
#region Authentication ...
[StringValue("Account/DiscoveryDocument")]
DiscoveryDocument,
[StringValue("Account/RequestScopeAccessToken")]
RequestScopeAccessToken,
[StringValue("Account/Authenticate")]
Authenticate,
[StringValue("Account/Login")]
Login,
[StringValue("Account/RefreshTokens")]
RefreshTokens,
[StringValue("Account/ChangePassword")]
ChangePassword,
[StringValue("Account/ResetPassword")]
ResetPassword,
#endregion
//
#region Proile ...
[StringValue("Account/Profile/{ids}/GetNames")]
GetNames,
[StringValue("Account/Profile/GetNameIds")]
GetNameIds,
[StringValue("Account/Profile/{userSelectByParam}")]
GetProfile,
[StringValue("Account/Profile/Query")]
QueryProfiles,
[StringValue("Account/Profile/Avatars/Query/{userSelectByParam}")]
QueryAvatars,
[StringValue("Account/Profile/Update/{userSelectByParam}")]
UpdateProfile,
[StringValue("Account/Profile/{userSelectByParam}")]
FullUpdateProfile,
[StringValue("Account/Profile/Avatar")]
AddAvatar,
[StringValue("Account/Profile/Avatars")]
AddAvatars,
[StringValue("Account/Profile/Avatars/{ids}")]
RemoveAvatars,
[StringValue("Account/Profile/Avatars/{id}/Set")]
SetAvatar,
#endregion
//
#region Search ...
[StringValue("Account/OpenToSearch/Query")]
QueryOpenToSearchProfiles,
#endregion
//
#region Registration ...
[StringValue("Account/CanRegisterUserName/{userName}")]
CanRegisterUserName,
[StringValue("Account/CanRegisterMobileNumber/{mobileNumber}")]
CanRegisterMobileNumber,
[StringValue("Account/CanRegisterEmail/{email}")]
CanRegisterEmail,
[StringValue("Account/IsConfirmedEmail")]
IsConfirmedEmail,
[StringValue("Account/IsConfirmedMobile")]
IsConfirmedMobile,
[StringValue("Account/ConfirmRegistration")]
ConfirmRegistration,
[StringValue("Account/ConfirmMobileNumber")]
ConfirmMobileNumber,
[StringValue("Account/ConfirmEmailAddress")]
ConfirmEmailAddress,
[StringValue("Account/RequestConfirmMobile")]
RequestConfirmMobile,
[StringValue("Account/RequestConfirmEmail")]
RequestConfirmEmail,
[StringValue("Account/RequestResetPassword")]
RequestResetPassword,
[StringValue("Account/RequestConfirmRegistration")]
RequestConfirmRegistration,
[StringValue("Account/InviteUser")]
InviteUser,
[StringValue("Account/RequestRegistration")]
RequestRegistration,
[StringValue("Account/AddAccountInfo")]
AddAccountInfo,
[StringValue("Account/AttachProfileImage")]
AttachProfileImage,
[StringValue("Account/FinishRegistration")]
FinishRegistration,
#endregion
//
#region Friendship ...
[StringValue("Account/Friendship/{destUser}/Follow")]
Follow,
[StringValue("Account/Friendship/{destUser}/Cancel")]
Cancel,
[StringValue("Account/Friendship/{destUser}/UnFollowFollower")]
UnFollowFollower,
[StringValue("Account/Friendship/{destUser}/UnFollowFollowing")]
UnFollowFollowing,
[StringValue("Account/Friendship/{destUser}/Block")]
Block,
[StringValue("Account/Friendship/{destUser}/UnBlock")]
UnBlock,
[StringValue("Account/Friendship/{destUser}/AcceptRequest")]
AcceptRequest,
[StringValue("Account/Friendship/{destUser}/RejectRequest")]
RejectRequest,
[StringValue("Account/Friendship/{destUser}/FriendshipInfo")]
FriendshipInfo,
[StringValue("Account/Friendship/{destUser}/IsFollower")]
IsFollower,
[StringValue("Account/Friendship/{destUser}/FollowerState")]
FollowerState,
[StringValue("Account/Friendship/{destUser}/Follower")]
Follower,
[StringValue("Account/Friendship/Followers")]
Followers,
[StringValue("Account/Friendship/AllFollowers")]
AllFollowers,
[StringValue("Account/Friendship/FollowersList")]
FollowersList,
[StringValue("Account/Friendship/QueryFollowers")]
QueryFollowers,
[StringValue("Account/Friendship/{destUser}/IsFollowing")]
IsFollowing,
[StringValue("Account/Friendship/{destUser}/FollowingState")]
FollowingState,
[StringValue("Account/Friendship/{destUser}/Following")]
Following,
[StringValue("Account/Friendship/Followings")]
Followings,
[StringValue("Account/Friendship/AllFollowings")]
AllFollowings,
[StringValue("Account/Friendship/FollowingsList")]
FollowingsList,
[StringValue("Account/Friendship/QueryFollowings")]
QueryFollowings,
#endregion
//
#region Admin ...
[StringValue("Account/Ban")]
Ban,
[StringValue("Account/UnBan")]
UnBan,
[StringValue("Account/IsBanned/{userSelectByParam}")]
IsBanned,
#endregion
//
#region Open Actions ...
[StringValue("Account/Open")]
Open,
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XAuthenticationScheme.cs
using xExceptions.Attributes;
namespace xIdentityService.Constants {
public enum XAuthenticationScheme {
[StringValue ("token")]
XToken,
[StringValue ("introspection")]
XIntrospection,
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XHeader.cs
using xExceptions.Attributes;
namespace xIdentityService.Constants
{
///
/// All Available Headers ...
///
public enum XHeader
{
///
/// Hub Connection ID Header Keys ...
///
[StringValue("requestID")]
ConnectionId,
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XParam.cs
using xExceptions.Attributes;
namespace xIdentityService.Constants {
public enum XParam {
[StringValue ("Content-Type")]
XContentType,
[StringValue ("{boundary}")]
XBoundary,
[StringValue ("{userSelectByParam}")]
XUserSelectByParam,
[StringValue ("{destUser}")]
XDestUser,
[StringValue ("{id}")]
XId,
[StringValue ("{ids}")]
XIds,
[StringValue ("Origin")]
XOrigin,
[StringValue ("{userName}")]
XUserName,
[StringValue ("{mobileNumber}")]
XMobileNumber,
[StringValue ("{email}")]
XEmail,
[StringValue ("role")]
XRole,
[StringValue ("forceRole")]
XForceRole,
[StringValue ("IsRefreshed")]
XIsRefreshed,
[StringValue ("file")]
XFile,
[StringValue ("files")]
XFiles,
[StringValue ("actionToken")]
XActionToken,
[StringValue ("request")]
XRequest,
[StringValue ("scope")]
XScope,
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XProxyConstants.cs
namespace xIdentityService.Constants {
public struct XProxyConstants {
public const string XPROXY_HTTP_CLIENT = "XProxyHttpClient";
public const string XPROXY_FORWARD_HEADER = "xForwardHeader";
public const string XPROXY_ACCEPTED_HEADERS = "xAcceptedHeaders";
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XResponseContentTypes.cs
namespace xIdentityService.Constants {
public struct XResponseContentTypes {
public const string HTML = "text/html";
public const string JSON = "application/json";
public const string JavaScript = "text/javascript";
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Constants\XTokenType.cs
namespace xIdentityService.Constants {
public enum XTokenType {
//
// Summary:
// Self-contained Json Web Token
Jwt,
//
// Summary:
// Reference token
Reference
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityApiController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Attributes;
using xCommons.Configurations;
using xCommons.Providers;
using xIdentityService.Interfaces;
namespace xIdentityService.Controllers
{
///
/// Base Identity Api Controller
///
[ApiController]
[RequireXPowered(true)]
[Route("api/[controller]")]
[Produces("application/json")]
public abstract class XBaseIdentityApiController : XBaseIdentityController
{
protected XBaseIdentityApiController(
ILogger logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{ }
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityApiV1Controller.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Attributes;
using xCommons.Configurations;
using xCommons.Providers;
using xIdentityService.Interfaces;
namespace xIdentityService.Controllers
{
///
/// Base Identity Api V1 Controller
///
[ApiController]
[ApiVersion("1.0")]
[RequireXPowered(true)]
[Route("api/v{version:apiVersion}/[controller]")]
public abstract class XBaseIdentityApiV1Controller : XBaseIdentityApiController
{
protected XBaseIdentityApiV1Controller(
ILogger logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{ }
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Controllers\XBaseIdentityController.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Constants;
using xCommons.Controllers;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Models;
using xIdentityService.Constants;
using xIdentityService.Interfaces;
namespace xIdentityService.Controllers
{
public abstract class XBaseIdentityController : XBaseController
{
//
public IXIdentityProvider IdentityProvider { get; }
protected XBaseIdentityController(
ILogger logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider
) : base(
logger,
appConfiguration,
validationProvider
)
{
IdentityProvider = identityProvider;
}
//
#region NonActions ...
///
/// Retrieve Connection ID for Hubs ...
///
///
[NonAction]
public string GetConnectionId()
{
//
var result = "";
//
var headerKey = XHeader.ConnectionId.GetStringValue();
//
// Check if Connection ID is Provided ...
if (Request.Headers.ContainsKey(headerKey))
{
result = Request.Headers[headerKey];
}
//
return result;
}
///
/// Retrieve User Identifier Base on XActionRequest
///
///
///
///
///
[NonAction]
public string GetUserSelectByParam(
XActionRequest model,
bool forceNotNull = true,
ICollection excludes = null
)
{
//
// Validate Args ...
ValidationProvider.NotNull(model);
//
var result = IdentityProvider.GetUserSelectByParam(
model,
forceNotNull,
excludes
);
//
return result;
}
///
/// Retrieve Access Token
///
///
[NonAction]
public async Task GetAccessToken()
{
//
var accessToken = Request.Headers[XAuthorization.Header].ToString();
if (accessToken.IsNullOrEmpty())
{
//
accessToken = await HttpContext
.GetTokenAsync(XAuthorization.AccessToken);
}
//
if (accessToken
.ToNormalString()
.Contains(XAuthorization.TokenIdentifier
.ToNormalString()))
{
//
accessToken = accessToken
.Remove(0, XAuthorization.TokenIdentifier.Length);
}
//
return accessToken;
}
///
/// Retrieve Refresh Token
///
///
[NonAction]
public async Task GetRefreshToken()
{
//
var refreshToken = Request.Headers[XAuthorization.RefreshToken].ToString();
if (refreshToken.IsNullOrEmpty())
{
//
refreshToken = await HttpContext
.GetTokenAsync(XAuthorization.RefreshToken);
}
//
return refreshToken;
}
///
/// Retrieve Access Token Expiration Date
///
///
[NonAction]
public async Task GetTokenExpiresAt()
{
//
var expiresAtStr = Request.Headers[XAuthorization.ExpiresAt].ToString();
if (expiresAtStr.IsNullOrEmpty())
{
//
expiresAtStr = await HttpContext
.GetTokenAsync(XAuthorization.ExpiresAt);
}
//
var expiresAt = expiresAtStr.ConvertTo();
//
return expiresAt;
}
///
/// Retrieve All Required Tokens
///
///
[NonAction]
public async Task RetrieveTokensAsXLoginResponse()
{
//
var accessToken = await GetAccessToken();
var refreshToken = await GetRefreshToken();
var expiresAt = await GetTokenExpiresAt();
//
return new XLoginResponse
{
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
}
///
/// Retrieve All Required Tokens
///
///
[NonAction]
public async Task RetrieveTokensAsXTokenResponse()
{
//
var accessToken = await GetAccessToken();
var refreshToken = await GetRefreshToken();
var expiresAt = await GetTokenExpiresAt();
//
return new XTokenResponse
{
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
}
///
/// Retrive UserInfo
///
///
[NonAction]
public async Task GetUserInfo()
{
//
var claims = User.Claims ?? null;
if (!claims.HasChild())
{
return null;
}
var xTokens = await RetrieveTokensAsXTokenResponse();
var result = new XUserClaimsInfoDto(
xTokens.AccessToken,
xTokens.RefreshToken,
xTokens.ExpiresAt,
User.Claims
);
//
return result;
}
///
/// Validate User Authenticated and Retrieve User Info
///
///
[NonAction]
public async Task ValidateAndGetUserInfo()
{
//
if (!User.Identity.IsAuthenticated)
{
XException.NotAuthorized.Throw();
}
//
var result = await GetUserInfo();
if (result.IsNull())
{
XException.NotAuthorized.Throw();
}
//
return result;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\DI\XDIHelperExtension.cs
using System;
using IdentityModel.AspNetCore.OAuth2Introspection;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Authorization;
using xCommons.Extensions;
using xIdentityService.Configuration;
using xIdentityService.Constants;
using xIdentityService.Interfaces;
using xIdentityService.Providers;
using xIdentityService.Security;
namespace xIdentityService.DI {
public static partial class XDIHelperExtension {
///
/// Extract Module Configuration Structure from IConfiguration interface
///
///
///
public static XIdentityServiceConfiguration GetXIdentityServiceConfiguration (this IConfiguration config) {
//
var xIdentityServiceConfigSection = config.GetSection (ConfigurationNodeNames.IDENTITY_SERVICE_NODE_NAME);
return xIdentityServiceConfigSection.Get ();
}
///
/// Register Service and All it's Requirements
///
///
///
public static void AddXIdentityService (
this IServiceCollection services,
IConfiguration configuration,
ServiceLifetime lifeTime = ServiceLifetime.Singleton
) {
//
var identityConfiguration = configuration.GetXIdentityServiceConfiguration ();
AddIdentityService (
services,
identityConfiguration,
lifeTime
);
}
///
/// Register Service and All it's Requirements
///
///
///
public static void AddXIdentityService (
this IServiceCollection services,
XIdentityServiceConfiguration configuration,
ServiceLifetime lifeTime = ServiceLifetime.Singleton
) {
AddIdentityService (services, configuration, lifeTime);
}
///
/// Register Custome Token Provider
///
///
///
public static void AddXTokenProvider (
this IServiceCollection services,
ServiceLifetime lifetime = ServiceLifetime.Singleton)
where T : IXTokenProvider {
//
Console.WriteLine ("IdentityService: Add Custom Token Provider ...");
services.Add (new ServiceDescriptor (typeof (IXTokenProvider), typeof (T), lifetime));
}
///
/// Use Authentication
///
///
public static void UseXIdentityService (this IApplicationBuilder app) {
app.UseAuthentication ();
}
//
#region Private ...
private static void AddIdentityService (
this IServiceCollection services,
XIdentityServiceConfiguration config,
ServiceLifetime lifeTime = ServiceLifetime.Singleton
) {
//
services.AddSingleton (config);
//
var builder = services
.AddAuthentication (XAuthenticationScheme.XToken.GetStringValue ());
//
// Add JWT Handler ...
builder.AddJwtBearer (
XAuthenticationScheme.XToken.GetStringValue (), options => {
//
options.Authority = config.Authority;
options.TokenValidationParameters.ValidateAudience = false;
options.TokenValidationParameters.ValidTypes = new [] { "at+jwt" };
//
options.ForwardDefaultSelector = context => {
//
var path = context.Request.Path.Value;
//
var fromHeader = TokenRetrieval.FromAuthorizationHeader ();
var fromQuery = TokenRetrieval.FromQueryString ();
var bearerToken = fromHeader (context.Request) ?? fromQuery (context.Request);
//
var result = XAuthenticationScheme.XToken.GetStringValue ();
if (!bearerToken.IsNull () && !bearerToken.Contains (".")) {
result = XAuthenticationScheme.XIntrospection.GetStringValue ();
}
//
return result;
};
});
//
// Add OAuthIntrospect ...
builder.AddOAuth2Introspection (
XAuthenticationScheme.XIntrospection.GetStringValue (), options => {
//
options.Authority = config.Authority;
options.ClientId = config.ApiName;
options.ClientSecret = config.ClientSecret;
//
options.TokenRetriever = new Func (req => {
//
var fromHeader = TokenRetrieval.FromAuthorizationHeader ();
var fromQuery = TokenRetrieval.FromQueryString ();
//
var bearerToken = fromHeader (req) ?? fromQuery (req);
//
return bearerToken;
});
});
//
// Register Authorization Handler ...
services.AddSingleton ();
Console.WriteLine ("IdentityService: register Authorization Handlers ...");
//
// Register Identity Provider ...
services.Add (new ServiceDescriptor (typeof (IXIdentityProvider), typeof (XIdentityProvider), lifeTime));
Console.WriteLine ("IdentityService: Register IdentityProvider ...");
//
// Try To Register InMemoryTokenProvier if it's not Provided ...
IXTokenProvider xTokenProvider = null;
try {
xTokenProvider = services.GetRegisteredService ();
} catch { }
if (xTokenProvider.IsNull ()) {
//
Console.WriteLine ("IdentityService: there is no Custom Token Provider, Adding InMemoryTokenProvider instead ...");
services.Add (new ServiceDescriptor (typeof (IXTokenProvider), typeof (XInMemoryTokenProvider), lifeTime));
}
//
// Adding Security Provider ...
services.Add (new ServiceDescriptor (typeof (IXSecurityProvider), typeof (XSecurityProvider), lifeTime));
Console.WriteLine ("IdentityService: Register Security Provider ...");
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\AuthorizationPolicyBuilderExtensions.cs
using IdentityModel;
using Microsoft.AspNetCore.Authorization;
namespace xIdentityService.Extensions {
public static class AuthorizationPolicyBuilderExtensions {
///
/// Adds a policy to check for required scopes.
///
///
/// List of any required scopes. The token must contain at least one of the listed scopes.
///
public static AuthorizationPolicyBuilder RequireScope (this AuthorizationPolicyBuilder builder, params string[] scope) {
return builder.RequireClaim (JwtClaimTypes.Scope, scope);
}
}
///
/// Helper for creating scope-related policies
///
public static class ScopePolicy {
///
/// Creates a policy to check for required scopes.
///
/// List of any required scopes. The token must contain at least one of the listed scopes.
///
public static AuthorizationPolicy Create (params string[] scopes) {
return new AuthorizationPolicyBuilder ()
.RequireScope (scopes)
.Build ();
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\HttpContextExtensions.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Constants;
using xCommons.Extensions;
using xIdentityModels.Models;
using xIdentityService.Constants;
namespace xIdentityService.Extensions {
public static class HttpContextExtensions {
///
/// Retrieve Authentication Service ...
///
///
///
public static IAuthenticationService GetAuthenticationService (this HttpContext context) {
//
var result = context.RequestServices
.GetRequiredService ();
//
return result;
}
///
/// Retrieve Specific Token from HttpContext ...
///
///
///
///
///
public static async Task GetXTokenAsync (
this HttpContext context,
string tokenName,
XAuthenticationScheme scheme = XAuthenticationScheme.XToken
) {
//
// Validate Args ...
if (tokenName.IsNullOrEmpty ()) {
return null;
}
//
var authService = context.GetAuthenticationService ();
if (authService.IsNull ()) {
return null;
}
//
var authResult = await authService
.AuthenticateAsync (
context,
scheme
.GetStringValue ()
);
//
var result = authResult?.Properties?
.GetTokenValue (tokenName);
return result;
}
///
/// Retrieve Access Token
///
///
public static async Task GetAccessToken (this HttpContext context) {
//
var accessToken = context.Request.Headers[XAuthorization.Header]
.ToString ();
if (accessToken.IsNullOrEmpty ()) {
accessToken = await context
.GetTokenAsync (XAuthorization.AccessToken);
}
//
if (accessToken
.ToNormalString ()
.Contains (XAuthorization.TokenIdentifier
.ToNormalString ())) {
accessToken = accessToken
.Remove (0, XAuthorization.TokenIdentifier.Length);
}
//
return accessToken;
}
///
/// Retrieve Refresh Token
///
///
public static async Task GetRefreshToken (this HttpContext context) {
//
var refreshToken = context.Request.Headers[XAuthorization.RefreshToken]
.ToString ();
if (refreshToken.IsNullOrEmpty ()) {
refreshToken = await context
.GetTokenAsync (XAuthorization.RefreshToken);
}
//
return refreshToken;
}
///
/// Retrieve Access Token Expiration Date
///
///
public static async Task GetTokenExpiresAt (this HttpContext context) {
//
var expiresAtStr = context.Request.Headers[XAuthorization.ExpiresAt]
.ToString ();
if (expiresAtStr.IsNullOrEmpty ()) {
expiresAtStr = await context
.GetTokenAsync (XAuthorization.ExpiresAt);
}
//
var expiresAt = expiresAtStr.ConvertTo ();
//
return expiresAt;
}
///
/// Retrieve All Required Tokens
///
///
public static async Task RetrieveTokensAsXTokenResponse (HttpContext context) {
//
var accessToken = await GetAccessToken (context);
var refreshToken = await GetRefreshToken (context);
var expiresAt = await GetTokenExpiresAt (context);
//
return new XTokenResponse {
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\StreamExtensions.cs
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using xCommons.Extensions;
namespace xIdentityService.Extensions
{
public static partial class StreamExtensions
{
///
/// Converts an Stream to Async Enumerable ...
///
///
///
///
///
public static async IAsyncEnumerable ToAsyncEnumerable(
this Stream stream,
int bufferSize = 8192,
[System.Runtime.CompilerServices.EnumeratorCancellation]
CancellationToken cancellationToken = default
)
{
//
var buffer = new byte[bufferSize];
while (true)
{
//
int read = await stream
.ReadAsync(
buffer,
0,
buffer.Length,
cancellationToken
);
//
if (read == 0)
{
yield break;
}
//
yield return buffer.Take(read).ToArray();
}
}
///
/// Converts an Stream to Async Enumerable ...
///
///
///
///
///
public static async IAsyncEnumerable ToAsyncEnumerable(
this Stream stream,
int bufferSize = 8192,
[System.Runtime.CompilerServices.EnumeratorCancellation]
CancellationToken cancellationToken = default
)
{
//
var buffer = new byte[bufferSize];
while (true)
{
//
int read = await stream
.ReadAsync(
buffer,
0,
buffer.Length,
cancellationToken
);
if (read == 0)
{
yield break;
}
//
T chunk = default(T);
var readedBuffer = buffer.Take(read).ToArray();
var str = readedBuffer.FromBytes();
if (str.IsNullOrEmpty())
{
yield return chunk;
}
try
{
chunk = str.FromJSON();
}
catch
{ }
//
yield return chunk;
}
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XModelExtensions.cs
using xIdentityModels.Dtos;
using xModels.Dtos;
namespace xIdentityService.Extensions
{
public static class XModelExtensions
{
public static XPersonDto ToXPersonDto(this XOpenActionUserInfoDto source)
{
//
var result = new XPersonDto
{
Avatar = source.Avatar,
Lastname = source.Lastname,
Username = source.Username,
Firstname = source.Firstname,
};
//
return result;
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XTokenExtensions.cs
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using xCommons.Constants;
using xCommons.Extensions;
using xExceptions.Constants;
using xExceptions.Models;
using xIdentityModels.Models;
using xIdentityService.Interfaces;
public static partial class XTokenExtensions {
///
/// Retrieve Tokens From Headers
///
///
///
public static XLoginResponse RetrieveTokens (this HttpRequest source) {
//
var accessToken = source.Headers[XAuthorization.Header].ToString ();
var refreshToken = source.Headers[XAuthorization.RefreshToken].ToString ();
//
var expiresAtStr = source.Headers[XAuthorization.ExpiresAt].ToString ();
long expiresAt = expiresAtStr.ConvertTo ();
//
if (accessToken
.ToNormalString ()
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
}
//
return new XLoginResponse {
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
}
///
/// Retrieve Tokens From HttpContext
///
///
///
public static async Task RetrieveTokens (this HttpContext source) {
//
var accessToken = await source.GetTokenAsync (XAuthorization.AccessToken);
if (accessToken
.ToNormalString ()
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
}
var refreshToken = await source.GetTokenAsync (XAuthorization.RefreshToken);
var expiresAtStr = await source.GetTokenAsync (XAuthorization.ExpiresAt);
long expiresAt = expiresAtStr.ConvertTo ();
//
var headerRequestTokens = source.Request.RetrieveTokens ();
//
var result = new XLoginResponse {
AccessToken = accessToken ?? headerRequestTokens.AccessToken,
RefreshToken = refreshToken ?? headerRequestTokens.RefreshToken,
ExpiresAt = expiresAt != 0 ? expiresAt : headerRequestTokens.ExpiresAt
};
//
return result;
}
///
/// Retrieve Tokens From ActionExecutingContext
///
///
///
public static async Task RetrieveTokens (this ActionExecutingContext source) {
//
var result = await source.HttpContext.RetrieveTokens ();
return result;
}
///
/// Retrieve Tokens From XUserInfo instance
///
///
///
public static XTokenResponse RetrieveTokens (this XUserClaimsInfoDto source) {
//
var result = new XLoginResponse {
AccessToken = source.AccessToken,
RefreshToken = source.RefreshToken,
ExpiresAt = source.ExpiresAt
};
//
return result;
}
///
/// Retrieve Tokens From IHeader Dictionary
///
///
///
public static XLoginResponse RetrieveTokens (this IHeaderDictionary source) {
//
var accessToken = source[XAuthorization.Header].ToString () ?? "";
if (accessToken
.ToNormalString ()
.Contains (XAuthorization.TokenIdentifier.ToNormalString ())) {
accessToken = accessToken.Remove (0, XAuthorization.TokenIdentifier.Length);
}
//
var refreshToken = source[XAuthorization.RefreshToken].ToString () ?? "";
//
var expiresAtStr = source[XAuthorization.ExpiresAt].ToString () ?? "";
var expiresAt = expiresAtStr.ConvertTo ();
//
var result = new XLoginResponse {
AccessToken = accessToken,
RefreshToken = refreshToken,
ExpiresAt = expiresAt
};
//
return result;
}
///
/// Retrieve IXIdentityProvider from HttpContext
///
///
///
public static IXIdentityProvider GetXApiIdentityProvider (this FilterContext source) {
//
var services = source.HttpContext.RequestServices;
return (IXIdentityProvider) services
.GetService (typeof (IXIdentityProvider));
}
///
/// Generate XLoginResponse instance based on TokenResponse
///
///
///
public static XLoginResponse CreateXLoginResponse (this TokenResponse source) {
//
if (source.IsNull () ||
source.IsError) {
XException.InvalidToken.Throw ();
}
//
var expiresAt = new DateTimeOffset (DateTime.UtcNow)
.ToUnixTimeSeconds () +
source.ExpiresIn;
//
var result = new XLoginResponse {
AccessToken = source.AccessToken,
RefreshToken = source.RefreshToken,
ExpiresAt = expiresAt
};
//
return result;
}
///
/// Add Authorization Tokens in Headers of
/// Specific IHeaderDictionary instance
///
///
///
public static void SetXAuthenticationTokens (this IHeaderDictionary source, XLoginResponse model, string secret = null) {
//
source.Remove (XAuthorization.Header);
source.Remove (XAuthorization.RefreshToken);
source.Remove (XAuthorization.ExpiresAt);
source.Remove (XAuthorization.RevisionChecksum);
//
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
//
if (!secret.IsNullOrEmpty ()) {
var revisionChecksum = model.GetRevisionChecksum (secret);
source.Add (XAuthorization.RevisionChecksum, revisionChecksum);
}
}
///
/// Add Authorization Tokens in Headers of
/// Specific IHeaderDictionary instance
///
///
///
public static void SetXAuthenticationTokens (this HttpRequestHeaders source, XLoginResponse model) {
//
source.Remove (XAuthorization.Header);
source.Remove (XAuthorization.RefreshToken);
source.Remove (XAuthorization.ExpiresAt);
source.Remove (XAuthorization.RevisionChecksum);
//
source.Add (XAuthorization.Header, $"{XAuthorization.TokenIdentifier}{model.AccessToken}");
source.Add (XAuthorization.RefreshToken, $"{model.RefreshToken}");
source.Add (XAuthorization.ExpiresAt, $"{model.ExpiresAt}");
}
///
/// Add Authorization Tokens in Headers of
/// Specific HttpRequest instance
///
///
///
public static void SetXAuthenticationTokens (this HttpRequest source, XLoginResponse model) {
source.Headers.SetXAuthenticationTokens (model);
}
///
/// Add Authorization Tokens in Headers of
/// Specific HttpRequest instance
///
///
///
public static void SetXAuthenticationTokens (this HttpRequestMessage source, XLoginResponse model) {
source.Headers.SetXAuthenticationTokens (model);
}
///
/// Add ReNewed Authorization Tokens in Headers of
/// Specific Response.
/// Later in HttpInterceptors we can Look for AccessToken-ReNewed
/// header Value and Renew User Tokens based on it
///
///
///
public static void SetXAuthenticationTokens (this HttpResponse source, XLoginResponse model, string secret) {
source.Headers.SetXAuthenticationTokens (model, secret);
}
///
/// Determines a Token Can Refrsh or not
///
///
///
public static bool IsRefreshable (this XLoginResponse source) {
//
var containsTokenData = !source.IsNull () &&
!source.AccessToken.IsNullOrEmpty () &&
!source.RefreshToken.IsNullOrEmpty ();
if (!containsTokenData) {
return false;
}
//
var current = new DateTimeOffset (DateTime.UtcNow)
.ToUnixTimeSeconds ();
//
// var result = current > source.ExpiresAt || current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
var result = current > source.ExpiresAt - XAuthorization.ThresholdBeforeTokenExpiration;
//
return result;
}
///
/// Generate a Revision Checksum for new Tokens
///
///
///
///
public static string GetRevisionChecksum (this XLoginResponse source, string secret) {
return (source.AccessToken +
secret +
source.RefreshToken +
secret +
source.ExpiresAt.ToString ()
)
.ToMd5String ();
}
///
/// Generate a Revision Checksum for new Tokens
///
///
///
///
public static string GetRevisionChecksum (this XTokenResponse source, string secret) {
return (source.AccessToken +
secret +
source.RefreshToken +
secret +
source.ExpiresAt.ToString ()
)
.ToMd5String ();
}
///
/// Check an XLoginResponse instance is Valid with it's revision
///
///
///
///
///
public static bool ValidateRevisionChecksum (this XLoginResponse source, string checksum, string secret) {
//
var xChecksum = source.GetRevisionChecksum (secret);
return checksum == xChecksum;
}
///
/// Check an XTokenResponse instance is Valid with it's revision
///
///
///
///
///
public static bool ValidateRevisionChecksum (this XTokenResponse source, string checksum, string secret) {
//
var xChecksum = source.GetRevisionChecksum (secret);
return checksum == xChecksum;
}
///
/// Retrieve Exception Details if Fails
///
///
///
public static Exception GetException (this TokenResponse source) {
//
// Validate Args ...
if (source.IsNull () || !source.IsError) {
return XException.ActionFailed.ToException ();
}
//
XError error = source.ErrorDescription.FromJSON ();
return error.ToException ();
}
///
/// Convert XTokenResponse to Header Dictionary
///
///
///
public static IDictionary ToHeaderDictionary (this XTokenResponse source) {
//
var result = new Dictionary { { XAuthorization.RefreshToken, source.RefreshToken },
{ XAuthorization.ExpiresAt, source.ExpiresAt.ToString () }
};
//
return result;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Extensions\XUserClaimsInfoDtoExtensions.cs
using xCommons.Extensions;
using xIdentityModels.Constants;
using xIdentityModels.Models;
namespace xIdentityService.Extensions {
public static class XUserClaimsInfoDtoExtensions {
public static string GetUserSelectByParam (
this XUserClaimsInfoDto source,
XUserSelectBy userSelectBy = XUserSelectBy.Username
) {
//
var result = "";
//
switch (userSelectBy) {
//
case XUserSelectBy.ID:
result = source.UserId;
break;
//
case XUserSelectBy.Username:
result = source.UserName;
break;
//
case XUserSelectBy.Email:
result = source.Email;
break;
//
case XUserSelectBy.MobileNumber:
result = source.PhoneNumber;
break;
}
//
if (result.IsNullOrEmpty ()) {
//
if (!source.UserId.IsNullOrEmpty ()) {
result = source.UserId;
} else if (!source.UserName.IsNullOrEmpty ()) {
result = source.UserName;
} else if (!source.Email.IsNullOrEmpty ()) {
result = source.Email;
} else if (!source.PhoneNumber.IsNullOrEmpty ()) {
result = source.PhoneNumber;
}
}
//
return result;
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseIdentityHttpProvider.cs
using System;
using System.IO;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using RestSharp;
using xCommons.Providers;
using xHttpService.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Models;
using xIdentityService.Models;
namespace xIdentityService.Interfaces
{
///
/// an interface for Identity Provided Http Based Services ...
///
public interface IXBaseIdentityHttpProvider
{
///
/// Client Base Url ...
///
///
string BaseUrl { get; }
///
/// Logger ...
///
///
ILogger Logger { get; }
///
/// Powered Value ...
///
///
string XPoweredValue { get; }
///
/// Default Client Timeout ...
///
///
int DefaultClientTimeout { get; }
///
/// Default Buffering Chunk Size ...
///
///
int DefaultBufferingChunckSize { get; }
///
/// Validation Provider ...
///
///
XValidationProvider ValidationProvider { get; }
///
/// Get an Instance of Http Client
///
///
HttpClient GetHttpClient(XTokenResponse tokens = null);
HttpClient GetHttpClient(XUserClaimsInfoDto userInfo = null);
///
/// Get an Instance of RestClient
///
///
RestClient GetRestClient(XTokenResponse tokens = null);
RestClient GetRestClient(XUserClaimsInfoDto userInfo = null);
///
/// Get an Instance of RestRequest
///
///
///
///
///
///
///
RestRequest GetRestRequet(
Enum endpoint,
bool addXPoweredValue = true,
IDictionary @params = null,
IDictionary headers = null,
IDictionary queryStrings = null
);
///
/// Handle Call Specific Request and retrieve Response
///
///
///
///
///
///
///
///
Task RunRestRequest(
RestClient client,
RestRequest request,
XHttpMethod method,
bool supportRefreshingTokens = true,
CancellationToken cancellationToken = default
);
///
/// Access a Get Request Stream as AsyncEnumerable ...
///
///
///
///
///
///
///
///
///
///
///
Task StreamData(
Enum endpoint,
int bufferLength = 8194,
bool addXPoweredValue = true,
XTokenResponse tokens = null,
IDictionary @params = null,
IDictionary headers = null,
IDictionary queryStrings = null,
CancellationToken cancellationToken = default
);
///
/// Handle Call Specified Request and Retrieve XBaseRestResponse ...
///
///
///
///
///
///
///
/// an instance of XBaseRestResponse
Task> RunRestRequestByResponse(
RestClient client,
RestRequest request,
XHttpMethod method,
bool supportRefreshingTokens = true,
CancellationToken cancellationToken = default
);
///
/// Get User SelectBy Param
///
///
///
///
///
string GetUserSelectByParam(
XActionRequest model,
bool forceNotNull = true,
ICollection excludes = null
);
///
/// Converts UserInfo to TokenResponse model ...
///
///
///
XTokenResponse ToTokenResponse(XUserClaimsInfoDto userInfo = null);
///
/// Prepare Url Address of Specified Enum by Filling Params
/// and Query Strings Attach ...
///
///
///
///
///
///
string PrepareUrl(
Enum endpoint,
bool attachBaseUrl = false,
IDictionary @params = null,
IDictionary queryStrings = null
);
///
/// Prepare Url Address by Filling Params
/// and Query Strings Attach ...
///
///
///
///
///
///
string PrepareUrl(
string url,
bool attachBaseUrl = false,
IDictionary @params = null,
IDictionary queryStrings = null
);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseReferenced.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using xDataService.Models;
using xIdentityModels.Models;
using xModels.Base;
namespace xIdentityService.Interfaces
{
///
/// a Referenced Service is a Service which can Referenced to other Items ...
///
public interface IXBaseReferenced
where TEntity : XBaseEntity
{
///
/// Get Reference Identifier for Specified Provider and Specified Item ...
///
///
///
///
string GetIdentifier(
string providedFor,
TReferenceKey forProvidedId
);
///
/// Check Specified Item has Refernce to Provider ...
///
///
///
///
///
///
Task IsProvidedFor(
string providedFor,
TReferenceKey forProvidedId,
TKey id,
CancellationToken cancellationToken = default
);
///
/// Add Specified Reference to Specified Item ...
///
///
///
///
///
///
///
///
///
Task AddReference(
string providedFor,
TReferenceKey forProvidedId,
TKey id,
int forIndex = 0,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
);
///
/// Remove Specified Reference from Specified Item ...
///
///
///
///
///
///
///
///
///
Task RemoveReference(
string providedFor,
TReferenceKey forProvidedId,
TKey id,
int forIndex = 0,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
);
///
/// Get Specified References ...
///
///
///
///
///
///
Task>> GetReferences(
string providedFor,
TKey id,
CancellationToken cancellationToken = default
);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXBaseReferencedController.cs
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using xDataService.Models;
using xModels.Base;
namespace xIdentityService.Interfaces
{
public interface IXBaseReferencedController
where TEntity : XBaseEntity
{
///
/// Check an Item Has Reference to Specified ProvideFor and Specified forProvidedId ...
///
///
///
///
///
///
[HttpGet("{id}/Reference/IsProvidedFor")]
Task> IsProvidedFor(
[FromRoute] TKey id,
[FromQuery] string providedFor,
[FromQuery] object forProvidedId,
CancellationToken cancellationToken = default
);
///
/// Add a Reference to Item for Specified ProvideFor and Specified forProvidedId ...
///
///
///
///
///
///
///
[HttpPost("{id}/Reference")]
Task AddReference(
[FromRoute] TKey id,
[FromQuery] string providedFor,
[FromQuery] object forProvidedId,
[FromQuery] int forIndex = 0,
CancellationToken cancellationToken = default
);
///
/// Remove a Reference from Item for Specified ProvideFor and Specified forProvidedId ...
///
///
///
///
///
///
///
[HttpDelete("{id}/Reference")]
Task RemoveReference(
[FromRoute] TKey id,
[FromQuery] string providedFor,
[FromQuery] object forProvidedId,
[FromQuery] int forIndex = 0,
CancellationToken cancellationToken = default
);
///
/// Retrieve References of Specified Itemfor providedFor ...
///
///
///
///
///
[HttpGet("{id}/References")]
Task>>> GetReferences(
[FromRoute] TKey id,
[FromQuery] string providedFor,
CancellationToken cancellationToken = default
);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXIdentityBaseReferencedProvider.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using xDataService.Models;
using xIdentityModels.Models;
using xModels.Dtos;
namespace xIdentityService.Interfaces
{
///
/// in Some Cases we have Entities Which Can Referenced for Specified
/// Provider and Types ...
/// this interface Globaly introduce all available Actions for those ...
///
/// TKey: type of Provider Models Keys ...
/// TModel: type of Dto which Referenced ...
///
public interface IXIdentityBaseReferencedProvider
{
//
#region Props ...
///
/// Provider Identifier ...
///
string Provider { get; }
#endregion
//
#region Referenced Actions ...
///
/// Get Specified Indexed Reference for Specific Provided ID ...
///
///
///
///
Task GetReference(
TKey providedForId,
int forIndex = 0
);
///
/// Retrieve all Exists References of Specific Provided ID ...
///
///
///
Task> GetAllReferences(TKey providedForId);
///
/// Extract all Referencing Models for Specified Key ...
///
///
///
Task>> GetAllReferencings(TKey providedForId);
///
/// Count References ...
///
///
///
Task CountReferences(TKey providedForId);
///
/// Retrieve References of Specific Provided ID as Query ...
///
///
///
Task> QueryReferences(
XQuery query,
TKey providedForId
);
///
/// Add Reference a Model to Specific Provided ID ...
///
///
///
///
///
///
Task AddReference(
TModel model,
TKey providedForId,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
///
/// Add Reference a Model to Specific XRefence ...
///
///
///
///
///
///
Task AddReference(
TModel model,
XReference reference,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
///
/// Remove Reference a Model for Specific Provided ID ...
///
///
///
///
///
///
Task RemoveReference(
TModel model,
TKey providedForId,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
///
/// Remove Reference a Model for Specific XRefence ...
///
///
///
///
///
///
Task RemoveReference(
TModel model,
XReference reference,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
///
/// Remove All References to Specified Key ...
///
///
///
///
///
Task RemoveReferences(
TKey providedForId,
string connectionId = null,
XUserClaimsInfoDto userInfo = null
);
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXIdentityProvider.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Http;
using RestSharp;
using xHttpService.Constants;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityModels.Navigations;
using xModels.Dtos;
namespace xIdentityService.Interfaces
{
public partial interface IXIdentityProvider
{
//
string BaseUrl { get; }
string RevisionSecretKey { get; }
IXSecurityProvider SecurityProvider { get; }
//
#region Tools ...
string GetUserSelectByParam(
XActionRequest model,
bool forceNotNull = true,
ICollection excludes = null
);
#endregion
//
#region Tools ...
Task RunRestRequest(
RestClient client,
RestRequest request,
XHttpMethod method,
bool supportRefreshingTokens = false
);
#endregion
//
#region Authentication ...
Task RequestDiscoveryDocument();
Task RequestScopeAccessToken(string scope);
Task Introspection(XTokenResponse model);
Task Login(XLoginRequest model);
Task Logout(XTokenResponse model);
Task Authenticate(XLoginRequest model);
Task RefreshTokens(XTokenResponse model);
Task ChangePassword(
XTokenResponse tokens,
XActionRequest model
);
#endregion
//
#region Profile ...
Task> GetUserNames(
XTokenResponse tokens,
string userIds
);
Task> GetUserNameIds(
XTokenResponse tokens,
XUserNameIdRequest model
);
Task GetUserProfile(
XTokenResponse tokens,
string userSelectByParam
);
Task> QueryUsers(
XTokenResponse tokens,
XQuery query
);
Task> QueryInRoleUsers(
XTokenResponse tokens,
string role,
XQuery query,
bool forceRole = false
);
Task> QueryAvatars(
XTokenResponse tokens,
string userSelectByParam,
XQuery query
);
Task ProfileUpdateAsync(
XTokenResponse tokens,
string userSelectByParam,
XProfileUpdateRequest model
);
Task FullProfileUpdateAsync(
XTokenResponse tokens,
string userSelectByParam,
XProfileUpdateRequest request
);
Task AddAvatar(
XTokenResponse tokens,
IFormFile file
);
Task AddAvatars(
XTokenResponse tokens,
IFormFileCollection files
);
Task SetAvatar(
XTokenResponse tokens,
int avatarId
);
Task RemoveAvatars(
XTokenResponse tokens,
string avatarIds
);
#endregion
//
#region Search ...
///
/// Query Open To Search User Profiles ...
///
/// requested user's identifiers
/// how to filter results based on XQuery structure
/// an instance of XQueryResult of XUserProfileDto
Task> QueryOpenToSearchUsers(
XTokenResponse tokens,
XQuery query
);
#endregion
//
#region Registration ...
Task CanRegister(string userSelectByParam);
Task InviteUser(
XTokenResponse tokens,
XActionRequest model
);
Task RequestRegistration(
XActionRequest model
);
Task AddAccountInfo(
XActionRequest model
);
Task AttachProfileImage(
string actionToken,
IFormFile file
);
Task FinishRegistration(XActionRequest model);
Task IsConfirmedEmail(
XTokenResponse tokens,
string userSelectByParam
);
Task IsConfirmedMobile(
XTokenResponse tokens,
string userSelectByParam
);
Task RequestConfirmRegistration(XActionRequest model);
Task ConfirmRegistration(
XActionRequest model
);
Task RequestConfirmMobile(XActionRequest model);
Task ConfirmMobileNumber(XActionRequest model);
Task RequestConfirmEmail(XActionRequest model);
Task ConfirmEmailAddress(XActionRequest model);
Task RequestResetPassword(XActionRequest model);
Task ResetPassword(XActionRequest model);
#endregion
//
#region Friendship ...
Task Follow(
XTokenResponse tokens,
string destUser
);
Task Cancel(
XTokenResponse tokens,
string destUser
);
Task UnFollowFollower(
XTokenResponse tokens,
string destUser
);
Task UnFollowFollowing(
XTokenResponse tokens,
string destUser
);
Task Block(
XTokenResponse tokens,
string destUser
);
Task UnBlock(
XTokenResponse tokens,
string destUser
);
Task AcceptRequest(
XTokenResponse tokens,
string destUser
);
Task RejectRequest(
XTokenResponse tokens,
string destUser
);
Task GetFriendshipInfo(
XTokenResponse tokens,
string destUser
);
Task IsFollower(
XTokenResponse tokens,
string destUser
);
Task GetFollower(
XTokenResponse tokens,
string destUser
);
Task GetFollowerState(
XTokenResponse tokens,
string destUser
);
Task> GetFollowers(XTokenResponse tokens);
Task> GetAllFollowers(XTokenResponse tokens);
Task> GetFollowingList(XTokenResponse tokens);
Task> QueryFollowers(
XQuery query,
string destUser,
XTokenResponse tokens
);
Task IsFollowing(
XTokenResponse tokens,
string destUser
);
Task GetFollowing(
XTokenResponse tokens,
string destUser
);
Task GetFollowingState(
XTokenResponse tokens,
string destUser
);
Task> GetFollowings(XTokenResponse tokens);
Task> GetAllFollowings(XTokenResponse tokens);
Task> GetFollowersList(XTokenResponse tokens);
Task> QueryFollowings(
XQuery query,
string destUser,
XTokenResponse tokens
);
#endregion
//
#region Admin ...
Task> Ban(
XTokenResponse tokens,
XUserNameIdRequest model
);
Task> UnBan(
XTokenResponse tokens,
XUserNameIdRequest model
);
Task IsBanned(
XTokenResponse tokens,
string userSelectByParam
);
#endregion
//
#region Open Actions ...
//
XDeviceDto GetDevice();
//
Task OpenGet(
XOpenActionInnerDto model
);
//
Task GetUserInfo(
XDeviceDto device,
string userSelectByParam
);
Task GetUserInfo(
XOpenActionInnerDto dto
);
Task GetUserInfo(
string token,
string request
);
//
Task> GetUserInfos(
XDeviceDto device,
string ids
);
Task> GetUserInfos(
XOpenActionInnerDto dto
);
Task> GetUserInfos(
string token,
string request
);
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXProxyHelper.cs
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using xIdentityService.Configuration;
namespace xIdentityService.Interfaces {
public interface IXProxyHelper {
///
/// Proxy Configuration ...
///
///
XProxyConfiguration Configuration { get; }
///
/// retrie Normalize Host ...
///
///
string NormalizeHost ();
///
/// Validate XProxy Configuration for Client ...
///
///
bool ValidateConfiguration ();
///
/// Retrieve all Prepared url of Routes ...
///
///
IEnumerable GetRouteUrls ();
///
/// retrieve all registred Routes ...
///
///
IEnumerable GetRoutes ();
///
/// Prepare a request url for a Proxy Route ...
///
///
///
///
string PrepareActionUrlForXProxyRoute (
string url,
XProxyRouteDescriptor descriptor
);
///
/// Prepare a request url for a Selected Proxy Route ...
///
///
///
///
string PrepareActionUrlForXProxyRoute (
string url,
Expression> whereClause
);
///
/// Find an Specific Route ...
///
///
///
XProxyRouteDescriptor FindRoute (Expression> whereClause);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXSecurityProvider.cs
namespace xIdentityService.Interfaces
{
public partial interface IXSecurityProvider
{
string Encrypt(string plainText);
string Decrypt(string cipherText);
string EncryptFromBytes(byte[] textBytes);
string DecryptFromBytes(byte[] cipherBytes);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Interfaces\IXTokenProvider.cs
using System.Threading.Tasks;
using xIdentityModels.Models;
namespace xIdentityService.Interfaces {
public partial interface IXTokenProvider {
Task IsTokenExists (string accessToken);
Task IsTokenExists (XTokenResponse tokens);
Task RemoveToken (string accessToken);
Task RemoveToken (XTokenResponse tokens);
Task RetrieveToken (string accessToken);
Task AddToken (XTokenResponse tokens);
Task UpdateToken (XTokenResponse tokens);
Task AddOrUpdateToken (XTokenResponse tokens);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Middlewares\XIdentityTokenRefresher.cs
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using xCommons.Constants;
using xCommons.Extensions;
using xIdentityModels.Extensions;
using xIdentityService.Interfaces;
namespace xIdentityService.Middlewares {
public partial class XIdentityTokenRefresherMiddleware {
//
#region Properties ...
private readonly ILogger logger;
private readonly RequestDelegate next;
private readonly IXTokenProvider tokenProvider;
private readonly IXIdentityProvider identityProvider;
#endregion
//
#region Constructor ...
public XIdentityTokenRefresherMiddleware (
RequestDelegate next,
ILoggerFactory loggerFactory,
IXTokenProvider tokenProvider,
IXIdentityProvider identityProvider
) {
//
this.next = next;
this.tokenProvider = tokenProvider;
this.identityProvider = identityProvider;
this.logger = loggerFactory
.CreateLogger ();
}
#endregion
//
#region Actions ...
public async Task Invoke (HttpContext context) {
//
// Handle Request ...
await HandleRequest (context);
//
// Do Main Task ...
try {
await next.Invoke (context);
} catch (Exception ex) {
logger.LogError ($"Error: {ex.Message}");
}
//
// Handle Response ...
await HandleResponse (context);
}
#endregion
//
#region Private ...
private async Task HandleRequest (HttpContext context) {
//
// Log ...
logger.LogInformation ($"Start Process Request ...");
//
// Check Access Token ...
var hasAccessToken = HasAccessToken (context);
if (!hasAccessToken) {
return;
}
//
// Check Access Token ...
var accessToken = GetAccessToken (context);
var isExists = await tokenProvider
.IsTokenExists (accessToken);
if (!isExists) {
return;
}
//
// Try Check is Refreshable ...
var tokens = await tokenProvider
.RetrieveToken (accessToken);
if (tokens.IsNull ()) {
return;
}
//
// Check is Expired or Refreshable ...
var isRefreshable = tokens.IsRefreshable ();
if (!isRefreshable) {
return;
}
//
// Refresh Token ...
var refreshedTokens = await identityProvider
.RefreshTokens (tokens);
if (refreshedTokens.IsNull ()) {
return;
}
//
// Set Refreshed AccessToken to Request ...
context
.Request
.Headers[XAuthorization.Header] =
$"{XAuthorization.TokenIdentifier}{refreshedTokens.AccessToken}";
}
private async Task HandleResponse (HttpContext context) {
//
// Log ...
logger.LogInformation ($"Start Process Response ...");
//
await Task.Run (() => { });
}
private bool HasAccessToken (HttpContext context) {
//
// Check Headers ...
if (context.IsNull () ||
context.Request.IsNull () ||
context.Request.Headers.IsNull ()) {
return false;
}
//
var result = context
.Request
.Headers
.ContainsKey (
XAuthorization.Header
);
//
return result;
}
private string GetAccessToken (HttpContext context) {
//
var hasAccessToken = HasAccessToken (context);
if (!hasAccessToken) {
return string.Empty;
}
//
// Get Result ...
var result = context
.Request
.Headers[
XAuthorization.Header
];
result = result
.ToString ()
.Replace (
XAuthorization.TokenIdentifier,
""
);
//
return result;
}
#endregion
}
///
/// Provide all DI Requirements for XIdentityTokenRefresher Middleware
///
public static class XIdentityTokenRefresherDIHelper {
///
/// Use XTokenValidator Middleware
///
///
public static void UseXIdentityTokenRefresher (this IApplicationBuilder app) {
app.UseMiddleware ();
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Middlewares\XProxyMiddleware.cs
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 {
///
/// Proxy Server Middleware ...
///
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 ...
///
/// Throw Required Exception ...
///
private void ThrowNotAuthorizedException () {
throw XException.NotAuthorized.ToException ();
}
///
/// Show propper logs if Enabled ...
///
///
///
private void SendLog (string message, LogLevel logLevel = LogLevel.Information) {
//
if (!CONFIGURATION.EnableLogging) {
return;
}
//
LogMessage (
message: message,
logLevel: logLevel
);
}
///
/// Log Proxy Server Configuration ...
///
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 ($" ");
});
}
///
/// Retrieve Destination Request Path based on Current Request ...
///
///
///
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;
}
///
/// Retrieve Propper Request Message based on HttpContext and uri ...F
///
///
///
///
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 {
[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;
}
///
/// Fill Request Message by provide HttpContext ...
///
///
///
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 acceptedHeaders = null;
var acceptedHeadersKeyValue = context.Request.Headers
.FirstOrDefault (hr =>
hr.Key == XProxyConstants.XPROXY_ACCEPTED_HEADERS
);
if (!acceptedHeadersKeyValue.IsNull ()) {
//
acceptedHeaders = acceptedHeadersKeyValue.Value
.ToString ()
.ParseListString ();
//
// 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 ()
);
}
}
///
/// Retreive and Extract Method Type of HttpRequest ...
///
///
///
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);
}
///
/// add all headers exists in HttpResponse MEssage to Current Context Response Headers ...
///
///
///
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");
}
///
/// Processing Response Content and Handle it on HttpContextResponse ...
///
///
///
///
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);
}
///
/// Check Content Type of Specific Response ...
///
///
///
///
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;
}
///
/// Retrieve and Extract Route Descriptor ...
///
///
///
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
}
///
/// Provide all requirements for Dependency Injection Handler ...
///
public static class XDIHelperExtension {
///
/// Retrieve XProxy Middelware Configuration from Configuration ...
///
///
///
public static XProxyConfiguration GetXProxyConfiguration (this IConfiguration config) {
//
var xProxyConfiguration = config.GetSection (ConfigurationNodeNames.XPROXY_CONFIGURATION_NODE_NAME);
return xProxyConfiguration.Get ();
}
///
/// Register HTTP Handler for XProxy Server ...
///
///
///
///
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
);
}
///
/// Register HTTP Handler for XProxy Server ...
///
///
///
///
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;
});
}
///
/// Register XProxy On Server ...
///
///
///
///
public static void AddXProxyServer (
this IServiceCollection services,
IConfiguration configuration,
HttpClientHandler httpHandler = null
) {
//
var proxyConfig = configuration.GetXProxyConfiguration ();
//
services.AddXProxyServer (
httpHandler: httpHandler,
configuration: proxyConfig
);
}
///
/// Register XProxy On Server ...
///
///
///
///
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 (configuration);
//
// Regiter Proxy Handler ...
services.AddXProxyHttpHandler (
httpHandler: httpHandler,
configuration: configuration
);
}
///
/// Register XProxy On Server ...
///
///
///
public static void AddXProxyClient (
this IServiceCollection services,
IConfiguration configuration
) {
//
var proxyConfig = configuration.GetXProxyConfiguration ();
//
services.AddXProxyClient (
configuration: proxyConfig
);
}
///
/// Register XProxy On Client ...
///
///
///
public static void AddXProxyClient (
this IServiceCollection services,
XProxyConfiguration configuration
) {
//
// Validate Args ...
if (configuration.IsNull ()) {
throw XException.InvalidConfiguration.ToException ();
}
//
// Register Proxy Configuration ...
services.AddSingleton (configuration);
//
// Register IXProxyHelper ...
services.AddSingleton ();
}
///
/// Adding XProxy Middleware to Applications ...
///
///
public static void UseXProxy (this IApplicationBuilder app) {
app.UseMiddleware ();
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Models\XBaseRestResponse.cs
using RestSharp;
namespace xIdentityService.Models
{
public class XBaseRestResponse
{
public T Model { get; set; }
public IRestResponse Response { get; set; }
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Admin.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using xCommons.Extensions;
using xHttpService.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
using xIdentityService.Constants;
namespace xIdentityService.Providers {
public partial class XIdentityProvider {
//
#region Admin ...
///
/// Ban Specific Users
///
/// Authentication Tokens
/// an instance of XUserNameIdRequest which represents user identifier list to Ban
/// a list of banned users identifiers
public async Task> Ban (
XTokenResponse tokens,
XUserNameIdRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (
tokens,
model
)
.AddNotEmpty (tokens.AccessToken)
.AddNotZeroChilds (model.Ids)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.Ban);
request.AddJsonBody (model);
//
var response = await RunRestRequest> (
client,
request,
XHttpMethod.POST
);
return response;
}
///
/// UnBann Specific Users
///
/// Authentication Tokens
/// an instance of XUserNameIdRequest which represents user identifier list to Ban
/// a list of unbanned users identifiers
public async Task> UnBan (
XTokenResponse tokens,
XUserNameIdRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (
tokens,
model
)
.AddNotEmpty (tokens.AccessToken)
.AddNotZeroChilds (model.Ids)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (XApiAccountEndpoint.UnBan);
request.AddJsonBody (model);
//
var response = await RunRestRequest> (
client,
request,
XHttpMethod.POST
);
return response;
}
///
/// Check Specific User is Banned or not
///
/// Authentication Tokens
/// specified user's identifier
/// a boolean value which represent user banned or not
public async Task IsBanned (
XTokenResponse tokens,
string userSelectByParam
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens)
.AddNotEmpty (
userSelectByParam,
tokens.AccessToken
)
.ValidateGroupAsync ();
//
var client = GetRestClient (tokens);
//
var request = GetRestRequet (
XApiAccountEndpoint.IsBanned,
@params : new Dictionary { { XParam.XUserSelectByParam.GetStringValue (), userSelectByParam } }
);
//
var response = await RunRestRequest (
client,
request,
XHttpMethod.GET
);
return response;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xIdentityService\Partial\XIdentityProvider+Authentication.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using IdentityModel.Client;
using xCommons.Extensions;
using xExceptions.Constants;
using xHttpService.Constants;
using xIdentityModels.Extensions;
using xIdentityModels.Models;
using xIdentityService.Constants;
namespace xIdentityService.Providers {
public partial class XIdentityProvider {
//
#region Authentication Handlers ...
///
/// Request for Discovery Document
///
/// an instance of DiscoveryDocumentResponse
public async Task RequestDiscoveryDocument () {
//
var httpClient = GetHttpClient ();
//
try {
//
var result = httpClient
.GetDiscoveryDocumentAsync (identityConfiguration.Authority)
.ContinueWith (docTask => {
//
httpClient.Dispose ();
return docTask.Result;
});
//
return await result;
} catch {
throw XException.ActionFailed.ToException ();
}
}
///
/// Request AccessToken for Specific XApiScope
///
/// a member of XApiScope
/// an instance of XTokenResponse
public async Task RequestScopeAccessToken (string scope) {
//
// Validate Args ...
var scopeName = string.Empty;
try {
scopeName = scope; // scope.GetStringValue ();
} catch { }
if (scopeName.IsNullOrEmpty ()) {
XException.InvalidArgs.Throw ();
}
//
var client = GetRestClient ();
var request = GetRestRequet (
XApiAccountEndpoint.RequestScopeAccessToken,
headers : new Dictionary { { XParam.XScope.GetStringValue (), scope.ToString () } });
//
var response = await RunRestRequest (
client,
request,
XHttpMethod.POST
);
//
// Save Token ...
if (!response.IsNull ()) {
await tokenProvider.AddOrUpdateToken (response);
}
//
return response;
}
///
/// Validate a token
///
/// Authentication Tokens
/// an instance of TokenIntrospectionResponse
public async Task Introspection (XTokenResponse model) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (model.AccessToken)
.ValidateGroupAsync ();
//
var httpClient = GetHttpClient ();
//
try {
//
var discoDoc = await RequestDiscoveryDocument ();
if (discoDoc.IsError) {
XException.ActionFailed.Throw ();
}
//
var response = await httpClient.IntrospectTokenAsync (new TokenIntrospectionRequest {
//
Address = discoDoc.IntrospectionEndpoint,
ClientId = identityConfiguration.ClientId,
ClientSecret = identityConfiguration.ClientSecret,
//
Token = model.AccessToken
});
if (response.IsError) {
throw new Exception (response.Error);
}
//
return response;
} catch {
throw XException.ActionFailed.ToException ();
}
}
///
/// Authenticate a User
///
/// User Login Required Info, an instance of XLoginRequest
/// an instance of XTokenResponse
public async Task Authenticate (XLoginRequest model) {
//
// Validate Args ...
validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (
model.UserSelectBy,
model.Password
)
.ValidateGroup ();
//
var client = GetRestClient ();
var request = GetRestRequet (XApiAccountEndpoint.Authenticate);
request.AddJsonBody (model);
//
var response = await RunRestRequest (
client,
request,
XHttpMethod.POST
);
//
// Save Token ...
if (!response.IsNull ()) {
await tokenProvider.AddOrUpdateToken (response);
}
//
return response;
}
///
/// Do Login based on XLoginRequest
///
/// User Login Required Info, an instance of XLoginRequest
/// an instance of XTokenResponse
public async Task Login (XLoginRequest model) {
//
// Validate Args ...
validationProvider
.GroupValidationBuilder ()
.AddNotNull (model, model.Device)
.AddNotEmpty (
model.UserSelectBy,
model.Password
)
.ValidateGroup ();
//
var client = GetRestClient ();
var request = GetRestRequet (XApiAccountEndpoint.Login);
request.AddJsonBody (model);
//
var response = await RunRestRequest (
client,
request,
XHttpMethod.POST
);
//
if (!response.IsNull ()) {
//
var tokens = response.ToXTokenResponse ();
await tokenProvider.AddOrUpdateToken (tokens);
}
//
return response;
}
///
/// Logout from System
///
///
///
public async Task Logout (XTokenResponse model) {
//
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (model.AccessToken)
.ValidateGroupAsync ();
//
var isExists = await tokenProvider
.IsTokenExists (model.AccessToken);
if (isExists) {
await tokenProvider
.RemoveToken (model.AccessToken);
}
}
///
/// Refresh Tokens
///
/// Authentication Tokens
/// an instance of XTokenResponse
public async Task RefreshTokens (XTokenResponse model) {
//
// Validate Args ...
validationProvider
.GroupValidationBuilder ()
.AddNotNull (model)
.AddNotEmpty (
model.AccessToken,
model.RefreshToken
)
.ValidateGroup ();
//
var client = GetRestClient (model);
//
var request = GetRestRequet (
XApiAccountEndpoint.RefreshTokens,
headers : model.ToHeaderDictionary ());
request.AddJsonBody (model);
//
var response = await RunRestRequest (
client,
request,
XHttpMethod.POST
);
if (!response.IsNull ()) {
await tokenProvider.UpdateToken (response);
}
//
return response;
}
#endregion
//
#region Password Actions Handlers ...
///
/// Change Password
///
/// Authentication Tokens
/// an instance of XActionRequest class which provider requirement for action
///
public async Task ChangePassword (
XTokenResponse tokens,
XActionRequest model
) {
//
// Validate Args ...
await validationProvider
.GroupValidationBuilder ()
.AddNotNull (tokens, model)
.AddNotEmpty (
model.Lang,
model.Password,
model.NewPassword,
model.ReturnUrl)
.AddNotNull (model.Device)
.ValidateGroupAsync ();
//
// Validate User Select By Param ...
var userSelectByParam = GetUserSelectByParam (
model,
forceNotNull : true,
excludes : null);
//
var client = GetRestClient (tokens);
var request = GetRestRequet (
XApiAccountEndpoint.ChangePassword,
headers : tokens.ToHeaderDictionary ());
request.AddJsonBody (model);
//
var response = await RunRestRequest