public async Task <IActionResult> Get(int?id, [FromServices] IApplicationContext applicationContext, [FromServices] IContainerResolve containerResolve) { if (applicationContext.Principal.Authorization.Operations.Count == 0) { return(Unauthorized()); } string accessToken = null; int index = id.HasValue ? id.Value : 1; if (applicationContext.Principal.Identity is ClaimsIdentity claimsIdentity) { if (null != claimsIdentity.BootstrapContext) { accessToken = claimsIdentity.BootstrapContext.ToString(); } else { if (containerResolve.TryResolve <IKeyValueSettings>("OpenID", out var settings)) { if (containerResolve.TryResolve <ITokenProvider>(settings.Values[TokenKeys.ProviderIdKey], out var tokenProvider)) { accessToken = (await tokenProvider.GetTokenAsync(settings, claimsIdentity)).AccessToken; } } } } if (!String.IsNullOrEmpty(accessToken)) { var redirectUrl = Request.Query["redirectUrl"][0]; var redirectUri = redirectUrl.TrimEnd('/') + "/_content/Arc4u.Standard.OAuth2.Blazor/GetToken.html"; if (accessToken.Length > index * buffer) { containerResolve.TryResolve <IKeyValueSettings>("OAuth", out var settings); var thisController = settings.Values[TokenKeys.RootServiceUrlKey].TrimEnd('/') + $"/blazor/{index + 1}&redirectUrl={redirectUrl}&token={accessToken.Substring((index - 1) * buffer, buffer)}"; return(Redirect($"{redirectUri}?url={thisController}")); } else { return(Redirect($"{redirectUri}?token={accessToken.Substring((index - 1) * buffer, accessToken.Length - ((index - 1) * buffer))}")); } } return(BadRequest()); }
public ClaimsPrincipalMiddleware(RequestDelegate next, IContainerResolve container, ClaimsPrincipalMiddlewareOption option) { _next = next ?? throw new ArgumentNullException(nameof(next)); if (null == container) { throw new ArgumentNullException(nameof(container)); } if (null == option) { throw new ArgumentNullException(nameof(option)); } var logger = container.Resolve <ILogger <ClaimsPrincipalMiddleware> >(); if (!container.TryResolve <CacheContext>(out _cacheContext)) { logger.Technical().Information("No cache context is available.").Log(); } _option = option; _activitySource = container.Resolve <IActivitySourceFactory>()?.GetArc4u(); }
/// <summary> /// Create a JwtHttpHandler. Use services.AddHttpHandler to add one and <see cref="ConfigurePrimaryHttpMessageHandler"/> if you need to /// customize the HttpHandler. /// </summary> /// <param name="resolvingName">The name used to resolve the instance of the <see cref="IKeyValueSettings"/> implementation.</param> public JwtHttpHandler(IContainerResolve container, string resolvingName, IPlatformParameters parameters = null) { _container = container ?? throw new ArgumentNullException(nameof(container)); _logger = container.Resolve <ILogger <JwtHttpHandler> >(); if (!container.TryResolve(resolvingName, out _settings)) { _logger.Technical().System($"No settings for {resolvingName} is found.").Log(); } _parameters = parameters; _settingsName = null; container.TryResolve <IApplicationContext>(out _applicationContext); }
// On a frontend usage of the handler the application (user) context is always global => we don't have 2 users logged on the same application! // So the Handler is using the IContainerResolve which is not scoped and the IApplicationContext is also not scoped because everything is in fact registered as a Singleton. // So there is no issue to create even everything in the constructor. /// <summary> /// Create a JwtHttpHandler with settings <see cref="IKeyValueSettings"/> resolved based on the name "OAuth" and the <see cref="HttpMessageHandler"/> of type <see cref="HttpClientHandler"/>. /// </summary> public JwtHttpHandler(IContainerResolve container, IPlatformParameters parameters = null, bool skipValidateAuthenticationType = false) { _container = container ?? throw new ArgumentNullException(nameof(container)); _logger = container.Resolve <ILogger <JwtHttpHandler> >(); if (!container.TryResolve("OAuth", out _settings)) { _logger.Technical().System("No settings for OAuth is found.").Log(); } _parameters = parameters; _settingsName = null; container.TryResolve <IApplicationContext>(out _applicationContext); }
// on the backend, we have to retrieve the user context based on his scoped context when we do a request to another // service if this was done in the context of a user (via rest api or gRPC service). // When we do a call from a service account, in this case the user is fixed and not scoped => so the creation of the user in this // case can be a singleton because we do an impersonation! /// <summary> /// This is a ctor to use only in a backend scenario => where <see cref="IPlatformParameters"/> it is not used! /// No inner handler is defined because this will be done via the AddHttpClient method in a service! /// </summary> /// <param name="container">The scoped container</param> /// <param name="resolvingName">The name used to resolve the settings</param> public JwtHttpHandler(IContainerResolve container, ILogger <JwtHttpHandler> logger, string resolvingName) { _container = container ?? throw new ArgumentNullException(nameof(container)); _logger = logger; if (!container.TryResolve(resolvingName, out _settings)) { _logger.Technical().Debug($"No settings for {resolvingName} is found.").Log(); } container.TryResolve <IApplicationContext>(out _applicationContext); _parameters = _applicationContext; _settingsName = null; }
private IApplicationContext GetCallContext(out object parameters, out IContainerResolve containerResolve) { containerResolve = GetResolver(); // first priority to the scope one! if (null != _accessor?.HttpContext?.RequestServices) { var ctx = containerResolve.Resolve <IApplicationContext>(); parameters = ctx; // As this is global for an handler, this can be saved at the level of the class. // We do this here only when using an accessor => the IContainerResolve is only available in the context of a call not // when the JwtHttpHandler is built. if (null == _settings && !String.IsNullOrWhiteSpace(_settingsName)) { if (!containerResolve.TryResolve(_settingsName, out _settings)) { _logger.Technical().Debug($"No settings for {_settingsName} is found.").Log(); } } return(ctx); } parameters = _parameters; return(_applicationContext); }
private async Task <TokenInfo> GetOpenIdTokenAsync(IKeyValueSettings settings, ClaimsIdentity identity) { // Check the information. var messages = new Messages(); if (null == settings) { throw new AppException(new Message(ServiceModel.MessageCategory.Technical, MessageType.Error, "Settings parameter cannot be null.")); } var settingsProviderName = settings.Values.ContainsKey("OpenIdSettingsReader") ? settings.Values["OpenIdSettingsReader"] : "OpenID"; if (Container.TryResolve <IKeyValueSettings>(settingsProviderName, out var openIdSettings)) { if (!openIdSettings.Values.ContainsKey(TokenKeys.ProviderIdKey)) { messages.Add(new Message(ServiceModel.MessageCategory.Technical, MessageType.Error, "No Provider defined in OpenId Settings.")); } else { var tokenProviderName = openIdSettings.Values[TokenKeys.ProviderIdKey]; if (Container.TryResolve <ITokenProvider>(tokenProviderName, out var openIdTokenProvider)) { return(await openIdTokenProvider.GetTokenAsync(openIdSettings, identity)); } else { messages.Add(new Message(ServiceModel.MessageCategory.Technical, MessageType.Error, $"Cannot resolve a token provider with name {tokenProviderName}.")); } } } else { messages.Add(new Message(ServiceModel.MessageCategory.Technical, MessageType.Error, $"Cannot resolve the KeyValues settings with name {settingsProviderName}.")); } messages.LogAndThrowIfNecessary(this); messages.Clear(); return(null); }
public IObjectSerialization Serializer(string keyName) { var handlerDefinition = _definitions.Get(keyName); if (null == handlerDefinition.Serializer || !_serviceProvider.TryResolve <IObjectSerialization>(handlerDefinition.Serializer, out var serializerFactory)) { return(_serviceProvider.Resolve <IObjectSerialization>()); } return(serializerFactory); }
/// <summary> /// Create a JwtHttpHandler. Use services.AddHttpHandler to add one and <see cref="ConfigurePrimaryHttpMessageHandler"/> if you need to /// customize the HttpHandler. /// </summary> /// <param name="settings">The settings needed for the <see cref="ITokenProvider"/>.</param> /// <param name="handler">The handler, can be a <see cref="DelegatingHandler"/></param> public JwtHttpHandler(IContainerResolve container, IKeyValueSettings settings, IPlatformParameters parameters = null) { _container = container ?? throw new ArgumentNullException(nameof(container)); _logger = container.Resolve <ILogger <JwtHttpHandler> >(); _settings = settings ?? throw new ArgumentNullException(nameof(settings)); _parameters = parameters; _settingsName = null; container.TryResolve <IApplicationContext>(out _applicationContext); }
private IObjectSerialization GetSerializer(PubSubDefinition definition) { if (null == definition) { throw new ArgumentNullException(nameof(definition)); } if (null == definition.Serializer || !_serviceProvider.TryResolve <IObjectSerialization>(definition.Serializer, out var serializerFactory)) { return(_serviceProvider.Resolve <IObjectSerialization>()); } return(serializerFactory); }
private void InitializeFromConfig(IConfiguration configuration) { lock (_lock) { if (null == configuration) { return; } var config = new Configuration.Caching(); configuration.Bind("Caching", config); Principal = config.Principal; if (null != config.Default && !String.IsNullOrWhiteSpace(config.Default)) { _cacheConfigName = config.Default; if (null != config.Caches) { // retrieve the caches and start if asked! foreach (var cacheConfig in config.Caches) { if (cacheConfig.IsAutoStart) { if (_dependency.TryResolve <ICache>(cacheConfig.Kind, out var cache)) { cache.Initialize(cacheConfig.Name); _caches.Add(cacheConfig.Name, cache); _logger.Technical().From <CacheContext>().System($"Instantiate a new instance of a cache with a kind of {cacheConfig.Kind} and named {cacheConfig.Name}.").Log(); } else { _logger.Technical().From <CacheContext>().Error($"Cannot resolve an ICache instance with the name: {cacheConfig.Kind}.").Log(); } } else { _uninitializedCaches.Add(cacheConfig.Name, cacheConfig.Kind); _logger.Technical().From <CacheContext>().System($"Register a cache with a kind of {cacheConfig.Kind} and named {cacheConfig.Name} for later.").Log(); } } } } } }
public Cache(ILogger logger, IContainerResolve container, string identifier) { Logger = logger; if (!container.TryResolve(out TokenCache)) { Logger.Technical().From <Cache>().Error("No implementation for an ITokenCache exists! Check your dependencies.").Log(); Logger.Technical().From <Cache>().System($"Token cache is skipped for the user identifier: {identifier}.").Log(); } _identifier = identifier; // Attach the events. BeforeAccess += BeforeAccessNotification; AfterAccess += AfterAccessNotification; }
public MessagesScope(IContainerResolve container, ILogger logger, string iocResolveName) { Logger = logger; // Create the unit of work list of messages. MessagesToPublish.Create(); // Search for the instance used to send commands and publish events on start of the // scope. So if we have a resolving issue, we know it immediately (and not after the work is done. if (!container.TryResolve <IEndpointConfiguration>(iocResolveName, out var endpointConfig)) { logger.Technical().From <MessagesScope>().Warning($"Unable to resolve the IEndpointConfiguration with the name '{iocResolveName}'").Log(); return; } if (null == endpointConfig.Instance) { logger.Technical().From <MessagesScope>().Warning($"Instance is null for the IEndpointConfiguration with the name '{iocResolveName}'").Log(); return; } _instance = endpointConfig.Instance; }
public ClientSecretAuthenticationMiddleware(RequestDelegate next, IContainerResolve container, ClientSecretAuthenticationOption option) { _next = next ?? throw new ArgumentNullException(nameof(next)); if (null == container) { throw new ArgumentNullException(nameof(container)); } if (null == option) { throw new ArgumentNullException(nameof(option)); } _logger = container.Resolve <ILogger <ClientSecretAuthenticationMiddleware> >(); _option = option; if (null == option.Settings) { _logger.Technical().Warning("No settings have been provided.").Log(); return; } if (option.Settings.Values.ContainsKey(TokenKeys.ProviderIdKey)) { _hasProvider = container.TryResolve(option.Settings.Values[TokenKeys.ProviderIdKey], out _provider); } if (!_hasProvider) { _logger.Technical().Warning("No ClientSecret provider found. Skip ClientSecret capability.").Log(); return; } _hasCertificate = null != option.Certificate && !String.IsNullOrWhiteSpace(option.Certificate.SecretKey) && !String.IsNullOrWhiteSpace(option.Certificate.Name); // check the certificate exists. if (_hasCertificate) { try { var certificateInfo = new CertificateInfo { Name = option.Certificate.Name }; if (Enum.TryParse(option.Certificate.FindType, out X509FindType x509FindType)) { certificateInfo.FindType = x509FindType; } if (Enum.TryParse(option.Certificate.Location, out StoreLocation storeLocation_)) { certificateInfo.Location = storeLocation_; } if (Enum.TryParse(option.Certificate.StoreName, out StoreName storeName_)) { certificateInfo.StoreName = storeName_; } _certificate = Certificate.FindCertificate( certificateInfo.Name, certificateInfo.FindType, certificateInfo.Location, certificateInfo.StoreName); _logger.Technical().System($"Authentication with certificate secret activated.").Log(); } catch (KeyNotFoundException) { _hasCertificate = false; _logger.Technical().Error($"No certificate found with {option.Certificate.FindType} = {option.Certificate.Name} in location = {option.Certificate.Location}.").Log(); } catch (Exception ex) { _logger.Technical().Exception(ex).Log(); } } else { _logger.Technical().System($"No authentication with certificate secret.").Log(); } _activitySource = container.Resolve <IActivitySourceFactory>()?.GetArc4u(); }
public BasicAuthenticationMiddleware(RequestDelegate next, IContainerResolve container, BasicAuthenticationContextOption option) { _next = next ?? throw new ArgumentNullException(nameof(next)); if (null == container) { throw new ArgumentNullException(nameof(container)); } if (null == option) { throw new ArgumentNullException(nameof(option)); } if (null == option.Settings) { throw new ArgumentNullException("Settings defined in option cannot be null."); } _logger = container.Resolve <ILogger <BasicAuthenticationMiddleware> >(); if (!string.IsNullOrEmpty(option.DefaultUpn)) { if (!Regex.IsMatch(option.DefaultUpn, @"^@([a-zA-Z0-9]+\.[a-zA-Z0-9]+)")) { _logger.Technical().Warning($"Bad upn format, we expect a @ and one point.").Log(); option.DefaultUpn = string.Empty; } else { _logger.Technical().Information($"Default upn: {option.DefaultUpn}.").Log(); } } if (option.Settings.Values.ContainsKey(TokenKeys.ProviderIdKey)) { _hasProvider = container.TryResolve(option.Settings.Values[TokenKeys.ProviderIdKey], out _provider); if (!_hasProvider) { _logger.Technical().Error($"No token provider was found with resolution name equal to: {option.Settings.Values[TokenKeys.ProviderIdKey]}.").Log(); } } else { _logger.Technical().Error($"No token provider resolution name is defined in your settings!").Log(); } if (!_hasProvider) { _logger.Technical().Error($"Basic Authentication capability is deactivated!").Log(); } if (!container.TryResolve(out _tokenCache)) { _logger.Technical().Error($"No token ache are defined for Basic Authentication.").Log(); } _option = option; _container = container; _activitySource = container.Resolve <IActivitySourceFactory>()?.GetArc4u(); }
private void AddBearerTokenCallerMetadata <TRequest, TResponse>(ref ClientInterceptorContext <TRequest, TResponse> context) where TRequest : class where TResponse : class { var headers = context.Options.Headers; // Call doesn't have a headers collection to add to. // Need to create a new context with headers for the call. if (headers == null) { headers = new Metadata(); var options = context.Options.WithHeaders(headers); context = new ClientInterceptorContext <TRequest, TResponse>(context.Method, context.Host, options); } // if we have already an "Authorization" defined, we can skip the code here. if (null != headers.GetValue("authorization")) { _logger.Technical().System($"Authorization header found. Skip adding a bearer token for AuthenticationType: {_settings.Values[TokenKeys.AuthenticationTypeKey]}.").Log(); return; } if (null != _accessor) { _container = _accessor.HttpContext.RequestServices.GetService <IContainerResolve>(); } // As this is global for an handler, this can be saved at the level of the class. // We do this here only when using an accessor => the IContainerResolve is only available in the context of a call not // when the JwtHttpHandler is built. if (null == _settings && !String.IsNullOrWhiteSpace(_settingsName)) { if (!_container.TryResolve(_settingsName, out _settings)) { _logger.Technical().Debug($"No settings for {_settingsName} is found.").Log(); } } if (_container.TryResolve <IApplicationContext>(out var applicationContext)) { _platformParameter = _platformParameter ?? applicationContext?.Principal?.Identity as ClaimsIdentity; } if (!_settings.Values.TryGetValue(TokenKeys.AuthenticationTypeKey, out var authenticationType)) { _logger.Technical().System($"No antuentication type for {this.GetType().Name}, Check next Interceptor").Log(); return; } var inject = authenticationType.Equals("inject", StringComparison.InvariantCultureIgnoreCase); // Skip (BE scenario) if the parameter is an identity and the settings doesn't correspond to the identity's type. if (_platformParameter is ClaimsIdentity claimsIdentity && !inject && !claimsIdentity.AuthenticationType.Equals(_settings.Values[TokenKeys.AuthenticationTypeKey], StringComparison.InvariantCultureIgnoreCase)) { return; } // But in case we inject we need something in the platformParameter! if (null == _platformParameter && !inject) { return; } try { ITokenProvider provider = _container.Resolve <ITokenProvider>(_settings.Values[TokenKeys.ProviderIdKey]); var tokenInfo = provider.GetTokenAsync(_settings, _platformParameter).Result; if (tokenInfo.ExpiresOnUtc < DateTime.UtcNow) { _logger.Technical().System($"Token is expired! Next Interceptor will be called.").Log(); return; } headers.Add("authorization", $"Bearer {tokenInfo.AccessToken}"); } catch (Exception ex) { _logger.Technical().Exception(ex).Log(); } // Add culture and activityID if exists! if (null != applicationContext?.Principal) { if (null != applicationContext.Principal?.ActivityID && null == headers.GetValue("activityid")) { _logger.Technical().System($"Add the activity id to the request for tracing purpose: {applicationContext.Principal.ActivityID}.").Log(); headers.Add("activityid", applicationContext.Principal.ActivityID.ToString()); } var culture = applicationContext.Principal.Profile?.CurrentCulture?.TwoLetterISOLanguageName; if (null != culture && null == headers.GetValue("culture")) { _logger.Technical().System($"Add the current culture to the request: {applicationContext.Principal.Profile?.CurrentCulture?.TwoLetterISOLanguageName}").Log(); headers.Add("culture", culture); } } }