Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        public async Task Invoke(HttpContext context)
        {
            if (context.User.Identity.IsAuthenticated && context.User.Identity.AuthenticationType.Equals(_options.OpenIdSettings.Values[TokenKeys.AuthenticationTypeKey], StringComparison.InvariantCultureIgnoreCase))
            {
                if (context.User is AppPrincipal principal)
                {
                    context.Request?.Headers?.Add("activityid", principal?.ActivityID.ToString() ?? Guid.NewGuid().ToString());
                    if (null != principal?.Profile?.CurrentCulture)
                    {
                        context.Request?.Headers?.Add("culture", principal.Profile.CurrentCulture.TwoLetterISOLanguageName);
                    }
                }

                IContainerResolve container = (IContainerResolve)context.RequestServices.GetService(typeof(IContainerResolve));

                // Not thread safe => can call activity source factory more than one but factory implementation is thread safe => so few calls on the start of the service is a possibility.
                if (!hasAlreadyTriedToResolve)
                {
                    hasAlreadyTriedToResolve = true;
                    _activitySource          = container.Resolve <IActivitySourceFactory>()?.GetArc4u();
                }

                using (var activity = _activitySource?.StartActivity("Inject bearer token in header", ActivityKind.Producer))
                {
                    ITokenProvider provider = container.Resolve <ITokenProvider>(_options.OpenIdSettings.Values[TokenKeys.ProviderIdKey]);

                    var tokenInfo = await provider.GetTokenAsync(_options.OpenIdSettings, context.User.Identity);

                    var authorization = new AuthenticationHeaderValue("Bearer", tokenInfo.AccessToken).ToString();
                    context.Request.Headers.Remove("Authorization");
                    context.Request.Headers.Add("Authorization", authorization);
                }
            }
            await _next.Invoke(context);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="containerResolve"></param>
        /// <param name="settingsName"></param>
        /// <param name="platformParameter"></param>
        public OAuth2Interceptor(IContainerResolve containerResolve, string settingsName, object platformParameter) : this(containerResolve)
        {
            _container = containerResolve ?? throw new ArgumentNullException(nameof(containerResolve));

            _settings = containerResolve.Resolve <IKeyValueSettings>(settingsName);

            // can be null.
            _platformParameter = platformParameter;
        }
Ejemplo n.º 5
0
        public async Task <IEnumerable <ClaimDto> > GetAsync(IIdentity identity, IEnumerable <IKeyValueSettings> settings, object parameter)
        {
            var result = new List <ClaimDto>();

            if (null == identity)
            {
                _logger.Technical().From <ClaimsBearerTokenExtractor>().Error($"A null identity was received. No Claims will be generated.").Log();
                return(result);
            }

            if (!(identity is ClaimsIdentity claimsIdentity))
            {
                _logger.Technical().From <ClaimsBearerTokenExtractor>().Error($"The identity received is not of type ClaimsIdentity.").Log();
                return(result);
            }

            if (null == settings || settings.Count() == 0)
            {
                _logger.Technical().From <ClaimsBearerTokenExtractor>().Error($"We need token settings to call the backend.").Log();
                return(result);
            }
            if (null == claimsIdentity.BootstrapContext && !settings.Any(s => s.Values.ContainsKey(TokenKeys.AuthenticationTypeKey) && s.Values[TokenKeys.AuthenticationTypeKey].Equals(identity.AuthenticationType)))
            {
                _logger.Technical().From <ClaimsBearerTokenExtractor>().System($"Skip fetching claims, no setting found for authentication type {identity.AuthenticationType}.");
                return(result);
            }

            try
            {
                JwtSecurityToken bearerToken = null;
                if (null != claimsIdentity.BootstrapContext)
                {
                    bearerToken = new JwtSecurityToken(claimsIdentity.BootstrapContext.ToString());
                }
                else
                {
                    // find the Provider for the AuthenticationType!
                    // exist because tested in the constructor!
                    var providerSettings = settings.First(s => s.Values[TokenKeys.AuthenticationTypeKey].Equals(identity.AuthenticationType));

                    ITokenProvider provider = _container.Resolve <ITokenProvider>(providerSettings.Values[TokenKeys.ProviderIdKey]);

                    Logger.Technical.From <ClaimsBearerTokenExtractor>().System("Requesting an authentication token.").Log();
                    var tokenInfo = await provider.GetTokenAsync(providerSettings, claimsIdentity);

                    bearerToken = new JwtSecurityToken(tokenInfo.AccessToken);
                }

                result.AddRange(bearerToken.Claims.Select(c => new ClaimDto(c.Type, c.Value)));
            }
            catch (Exception exception)
            {
                _logger.Technical().From <ClaimsBearerTokenExtractor>().Exception(exception).Log();
            }

            return(result);
        }
Ejemplo n.º 6
0
        /// <summary>Resolves service from container. Throws if unable to resolve.</summary>
        /// <param name="serviceType">Service type to resolve.</param>
        /// <param name="key">(optional) Service key to resolve.</param>
        /// <returns>Resolved service object.</returns>
        protected override object DoGetInstance(Type serviceType, string key)
        {
            if (serviceType == null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }
            var result = String.IsNullOrWhiteSpace(key) ? Container.Resolve(serviceType) : Container.Resolve(serviceType, key);

            return(result);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        /// <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);
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
 public QueueProcessorListener(CancellationToken stoppingToken,
                               QueueParameters queueParameters,
                               IQueueStreamManager queueStreamManager,
                               IMessageHandlerTypes messageHandlers,
                               IContainerResolve provider)
 {
     _stoppingToken            = stoppingToken;
     _queueParameters          = queueParameters;
     _queueStreamManager       = queueStreamManager;
     _logger                   = provider.Resolve <ILogger <QueueProcessorListener> >();
     _messageHandlers          = messageHandlers;
     _provider                 = provider;
     _hasThreadFinishToProcess = new AutoResetEvent(false);
 }
Ejemplo n.º 11
0
        // 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);
        }
Ejemplo n.º 12
0
        /// <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);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Method that will be used by NServiceBus to process a message.
        /// The real work is implemented in the Handle(T message) abstract method.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Handle(T message, IMessageHandlerContext context)
        {
            var messages = _container.Resolve <MessagesToPublish>();

            try
            {
                // business work to implement.
                await Handle(message);

                // Publish events.
                foreach (Object _event in messages.Events)
                {
                    try
                    {
                        await context.Publish(_event);
                    }
                    catch (System.Exception ex)
                    {
                        Logger.Technical.From(typeof(HandleMessageBase <T>)).Exception(ex).Log();
                    }
                }

                // Send commands.
                foreach (Object command in messages.Commands)
                {
                    try
                    {
                        await context.Send(command);
                    }
                    catch (System.Exception ex)
                    {
                        Logger.Technical.From(typeof(HandleMessageBase <T>)).Exception(ex).Log();
                    }
                }
            }
            catch (System.Exception ex)
            {
                Logger.Technical.From(typeof(HandleMessageBase <T>)).Exception(ex).Log();
            }
            finally
            {
                // Clear messages to avoid any sending of undesirable messages by
                // another message received on the bus.
                messages.Clear();
            }
        }
        public static IApplicationBuilder UseClientSecretAuthentication(this IApplicationBuilder app, IContainerResolve container, IKeyValueSettings settings, string settingsSectionName)
        {
            if (null == app)
            {
                throw new ArgumentNullException(nameof(app));
            }

            if (null == container)
            {
                throw new ArgumentNullException(nameof(container));
            }

            if (null == settings)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            var option = new ClientSecretAuthenticationOption(settings);

            container.Resolve <IConfiguration>().Bind(settingsSectionName, option);

            return(app.UseMiddleware <ClientSecretAuthenticationMiddleware>(container, option));
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Indexer to retrieve the <see cref="ICache"/> implementation based on the caching config section. The key is the cache name.
        /// </summary>
        /// <param name="cacheName"></param>
        /// <returns>An <see cref="ICache"/> implementation defined in the cache config section.</returns>
        /// <exception cref="ConfigurationErrorsException">Throw the exception when the cache name does not exist in the caching config section.</exception>
        public ICache this[string cacheName]
        {
            get
            {
                // look inside the collection if the cache is initialized.
                if (_caches.ContainsKey(cacheName))
                {
                    return(_caches[cacheName]);
                }

                // look if the cache is not yet started and start it.
                lock (_lock)
                {
                    if (_uninitializedCaches.ContainsKey(cacheName))
                    {
                        try
                        {
                            var cache = _dependency.Resolve <ICache>(_uninitializedCaches[cacheName]);

                            cache.Initialize(cacheName);

                            _caches.Add(cacheName, cache);
                            _uninitializedCaches.Remove(cacheName);

                            return(cache);
                        }
                        catch (Exception ex)
                        {
                            _logger.Technical().From <CacheContext>().Exception(ex).Log();
                        }
                    }
                }

                throw new InvalidOperationException($"There is no cache configured with the name {cacheName}.");
            }
        }
Ejemplo n.º 16
0
        public async Task Invoke(HttpContext context)
        {
            // Get the scoped instance of the container!
            IContainerResolve container = (IContainerResolve)context.RequestServices.GetService(typeof(IContainerResolve));
            var logger = container.Resolve <ILogger <ClaimsPrincipalMiddleware> >();

            try
            {
                // if we have some part of the site not in MVC (like swagger) and we need to force
                // authentication. We can add the start of the path to check and in this case we force a login!
                if (null != context.User && !context.User.Identity.IsAuthenticated)
                {
                    if (_option.OpenIdOptions.ForceAuthenticationForPaths.Any(r =>
                    {
                        return(r.Last().Equals('*') ?
                               context.Request.Path.Value.StartsWith(r.Remove(r.Length - 1), StringComparison.InvariantCultureIgnoreCase)
                            :
                               context.Request.Path.Value.Equals(r, StringComparison.InvariantCultureIgnoreCase));
                    }))
                    {
                        logger.Technical().System("Force an OpenId connection.").Log();
                        var cleanUri = new Uri(new Uri(context.Request.GetEncodedUrl()).GetLeftPart(UriPartial.Path));
                        if (Uri.TryCreate(_option.RedirectAuthority, UriKind.Absolute, out var authority))
                        {
                            cleanUri = new Uri(authority, cleanUri.AbsolutePath);
                        }
                        var properties = new AuthenticationProperties()
                        {
                            RedirectUri = cleanUri.ToString()
                        };
                        await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, properties);

                        return;
                    }
                }

                if (null != context.User && context.User.Identity.IsAuthenticated)
                {
                    logger.Technical().System("Create the principal.").Log();

                    // Add Telemetry.
                    using (var activity = _activitySource?.StartActivity("Create Arc4u Principal", ActivityKind.Producer))
                    {
                        // As the extension point can use some ITokenProvider based on the user.
                        // A dummy Principal is created based on the context identity!
                        // Must be registered as Scoped!
                        if (container.TryResolve <IApplicationContext>(out var applicationContext))
                        {
                            applicationContext.SetPrincipal(new AppPrincipal(new Authorization(), context.User.Identity, "S-1-0-0"));
                        }

                        // Load Claims from an external source if necessary!
                        if (_option.ClaimsFillerOptions.LoadClaimsFromClaimsFillerProvider)
                        {
                            await LoadExtraClaimsAsync(context, container, logger);
                        }

                        // Build an AppPrincipal.
                        AppPrincipal principal           = null;
                        var          profileFiller       = container.Resolve <IClaimProfileFiller>();
                        var          authorizationFiller = container.Resolve <IClaimAuthorizationFiller>();

                        var authorization = authorizationFiller.GetAuthorization(context.User.Identity);
                        var profile       = profileFiller.GetProfile(context.User.Identity);
                        principal = new AppPrincipal(authorization, context.User.Identity, profile.Sid)
                        {
                            Profile = profile
                        };

                        // Check if we have an ActivityID.
                        var activityIdHeader = context.Request?.Headers?.FirstOrDefault(h => h.Key.Equals("activityid", StringComparison.InvariantCultureIgnoreCase));

                        if (null == activityIdHeader || !activityIdHeader.HasValue || String.IsNullOrWhiteSpace(activityIdHeader.Value.Key) || StringValues.Empty == activityIdHeader.Value || activityIdHeader.Value.Value.Count == 0)
                        {
                            principal.ActivityID = Guid.NewGuid();
                        }
                        else
                        {
                            Guid activityId = Guid.Empty;
                            if (Guid.TryParse(activityIdHeader.Value.Value[0], out activityId) && activityId != Guid.Empty)
                            {
                                logger.Technical().Information($"Set the activity to the principal based on the caller information: {activityId}.").Log();
                            }
                            else
                            {
                                logger.Technical().Information($"The activity id given by the caller is not a valid Guid. A new one has been assigned.").Log();
                                activityId = Guid.NewGuid();
                            }

                            principal.ActivityID = activityId;
                        }
                        activity?.AddTag(LoggingConstants.ActivityId, principal.ActivityID);
                        // Check for a culture.
                        var cultureHeader = context.Request?.Headers?.FirstOrDefault(h => h.Key.Equals("culture", StringComparison.InvariantCultureIgnoreCase));
                        if (null != cultureHeader && cultureHeader.HasValue && StringValues.Empty != activityIdHeader.Value && cultureHeader.Value.Value.Count > 0)
                        {
                            try
                            {
                                principal.Profile.CurrentCulture = new CultureInfo(cultureHeader.Value.Value[0]);
                            }
                            catch (Exception ex)
                            {
                                logger.Technical().Exception(ex).Log();
                            }
                        }
                        logger.Technical().System("Set AppPrincipal to the HttpContext.User.").Log();
                        context.User = principal;

                        if (null != applicationContext)
                        {
                            logger.Technical().System("Set AppPrincipal to the ApplicationContext.").Log();
                            applicationContext.SetPrincipal(principal);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Technical().Exception(ex).Log();
            }

            await _next(context);
        }
Ejemplo n.º 17
0
 public static CacheContext GetCacheContext(this IContainerResolve container)
 {
     return(container.Resolve <CacheContext>());
 }
Ejemplo n.º 18
0
        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();
        }
Ejemplo n.º 19
0
        protected async Task <TokenInfo> CreateBasicTokenInfoAsync(IKeyValueSettings settings, CredentialsResult credential)
        {
            var basicTokenProvider = Container.Resolve <ICredentialTokenProvider>(CredentialTokenProvider.ProviderName);

            return(await basicTokenProvider.GetTokenAsync(settings, credential));
        }
Ejemplo n.º 20
0
 public static void InitializeTimeZoneContext(this IContainerResolve app)
 {
     app.Resolve <TimeZoneContext>();
 }
Ejemplo n.º 21
0
 // Add logging.
 private OAuth2Interceptor(IContainerResolve containerResolve)
 {
     _logger = containerResolve.Resolve <ILogger <OAuth2Interceptor> >();
 }
Ejemplo n.º 22
0
        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);
                }
            }
        }
        public async Task Invoke(HttpContext context)
        {
            if (context.User.Identity.IsAuthenticated && context.User.Identity.AuthenticationType.Equals(_options.AuthenticationType, StringComparison.InvariantCultureIgnoreCase))
            {
                // Check we have a valid token Adal token in cache?
                // if not, force authentication.
                ILogger <OpenIdCookieValidityCheckMiddleware> logger = null;
                try
                {
                    IContainerResolve container = (IContainerResolve)context.RequestServices.GetService(typeof(IContainerResolve));

                    // Not thread safe => can call activity source factory more than one but factory implementation is thread safe => so few calls on the start of the service is a possibility.
                    if (!hasAlreadyTriedToResolve)
                    {
                        hasAlreadyTriedToResolve = true;
                        _activitySource          = container.Resolve <IActivitySourceFactory>()?.GetArc4u();
                    }

                    TokenInfo tokenInfo = null;

                    using (var activity = _activitySource?.StartActivity("Validate bearer token expiration", ActivityKind.Producer))
                    {
                        activity?.AddTag("AuthenticationType", _options.AuthenticationType);

                        if (container.TryResolve <IApplicationContext>(out var applicationContext))
                        {
                            applicationContext.SetPrincipal(new AppPrincipal(new Authorization(), context.User.Identity, "S-1-0-0"));
                        }

                        logger = container.Resolve <ILogger <OpenIdCookieValidityCheckMiddleware> >();

                        ITokenProvider provider = container.Resolve <ITokenProvider>(_options.OpenIdSettings.Values[TokenKeys.ProviderIdKey]);

                        tokenInfo = await provider.GetTokenAsync(_options.OpenIdSettings, context.User.Identity);
                    }

                    if (null == tokenInfo)
                    {
                        throw new ApplicationException("Refresh Token is expired or invalid");
                    }

                    await _next.Invoke(context);
                }
                catch (Exception)
                {
                    _options.CookieManager.DeleteCookie(context, _options.CookieName, new CookieOptions());

                    logger?.Technical().System("Force an OpenId connection.").Log();
                    var cleanUri = new Uri(new Uri(context.Request.GetEncodedUrl()).GetLeftPart(UriPartial.Path));
                    if (Uri.TryCreate(_options.RedirectAuthority, UriKind.Absolute, out var authority))
                    {
                        cleanUri = new Uri(authority, cleanUri.AbsolutePath);
                    }
                    var properties = new AuthenticationProperties()
                    {
                        RedirectUri = cleanUri.ToString()
                    };
                    await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, properties);

                    return;
                }
            }
            else
            {
                await _next.Invoke(context);
            }
        }
Ejemplo n.º 24
0
        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();
        }