/// <summary>
    /// ASP.Net authentication & authorization, used by APIs and can be used
    /// by Services as well (for example, by SignalR hosts), but not by
    /// self-hosted services (e.g. with some custom TCP implementation).
    /// </summary>
    /// <returns></returns>
    public static IServiceCollection UseAspNetAuthentication(
        this IServiceCollection services,
        IAuthenticationInformationProvider authenticationInformationProvider)
    {
        services.AddTransient <RealtimeAuthenticationClient>();

        var profileAuthentication            = authenticationInformationProvider.GetProfileAuthenticationInformation();
        var serviceAuthentication            = authenticationInformationProvider.GetServiceAuthenticationInformation();
        var additionalProfileAuthentications = authenticationInformationProvider.GetAdditionalProfileAuthenticationInformations();

        if (profileAuthentication.TokenValidationParameters.ValidAudiences?.FirstOrDefault() == null ||
            (serviceAuthentication != null && serviceAuthentication.TokenValidationParameters.ValidAudiences?.FirstOrDefault() == null) ||
            additionalProfileAuthentications.Any(x => x.TokenValidationParameters.ValidAudiences?.FirstOrDefault() == null))
        {
            throw new InvalidOperationException("Call UseSomeProvider method on AuthenticationInformationBuilder before calling this method, so that ValidAudiences parameter is set up.");
        }

        var authenticationSchemes = new List <string>
        {
            profileAuthentication.SchemeName ?? throw new InvalidOperationException("Scheme name is empty.")
        };

        var authenticationBuilder = services
                                    .AddAuthentication(TyrAuthenticationSchemes.ProfileAuthenticationScheme) // Sets default authentication scheme.
                                    .AddJwtBearer(profileAuthentication.SchemeName, options => ConfigureOptions(options, profileAuthentication));

        foreach (var additionalAuthentication in additionalProfileAuthentications)
        {
            authenticationSchemes.Add(additionalAuthentication.SchemeName ?? throw new InvalidOperationException("Scheme name is empty."));
            authenticationBuilder.AddJwtBearer(additionalAuthentication.SchemeName, options => ConfigureOptions(options, additionalAuthentication));
        }

        if (serviceAuthentication != null)
        {
            authenticationSchemes.Add(serviceAuthentication.SchemeName ?? throw new InvalidOperationException("Scheme name is empty."));
            authenticationBuilder.AddJwtBearer(serviceAuthentication.SchemeName, options => ConfigureOptions(options, serviceAuthentication));
        }

        if (authenticationSchemes.Distinct().Count() != authenticationSchemes.Count)
        {
            throw new InvalidOperationException("Duplicate authentication schemes found.");
        }

        services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
                                    .RequireAuthenticatedUser()
                                    .AddAuthenticationSchemes(authenticationSchemes.ToArray())
                                    .Build();
        });

        services.AddTransient <IHttpContextAccessor, HttpContextAccessor>();
        services.AddTransient <IProfileTokenService, HttpContextProfileTokenService>();

        return(services);
    }
Esempio n. 2
0
 public ServiceTokenService(IAuthenticationInformationProvider authenticationInformationProvider)
 {
     _authenticationInformationProvider = authenticationInformationProvider;
 }