mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	Merge pull request #110 from sharpn/develop
Adding JWT authentication for use with auth0
This commit is contained in:
		@@ -6,6 +6,8 @@ using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Authentication.Handler.Creator
 | 
			
		||||
{
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
 | 
			
		||||
    using AuthenticationOptions = Configuration.AuthenticationOptions;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -17,15 +19,31 @@ namespace Ocelot.Authentication.Handler.Creator
 | 
			
		||||
        {
 | 
			
		||||
            var builder = app.New();
 | 
			
		||||
 | 
			
		||||
            builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
 | 
			
		||||
            if (authOptions.Provider.ToLower() == "jwt")
 | 
			
		||||
            {
 | 
			
		||||
                Authority = authOptions.ProviderRootUrl,
 | 
			
		||||
                ApiName = authOptions.ApiName,
 | 
			
		||||
                RequireHttpsMetadata = authOptions.RequireHttps,
 | 
			
		||||
                AllowedScopes = authOptions.AllowedScopes,
 | 
			
		||||
                SupportedTokens = SupportedTokens.Both,
 | 
			
		||||
                ApiSecret = authOptions.ApiSecret
 | 
			
		||||
            });
 | 
			
		||||
                var authenticationConfig = authOptions.Config as JwtConfig;
 | 
			
		||||
 | 
			
		||||
                builder.UseJwtBearerAuthentication(
 | 
			
		||||
                    new JwtBearerOptions()
 | 
			
		||||
                        {
 | 
			
		||||
                            Authority = authenticationConfig.Authority,
 | 
			
		||||
                            Audience = authenticationConfig.Audience
 | 
			
		||||
                        });
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                var authenticationConfig = authOptions.Config as IdentityServerConfig;
 | 
			
		||||
 | 
			
		||||
                builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
 | 
			
		||||
                {
 | 
			
		||||
                    Authority = authenticationConfig.ProviderRootUrl,
 | 
			
		||||
                    ApiName = authenticationConfig.ApiName,
 | 
			
		||||
                    RequireHttpsMetadata = authenticationConfig.RequireHttps,
 | 
			
		||||
                    AllowedScopes = authOptions.AllowedScopes,
 | 
			
		||||
                    SupportedTokens = SupportedTokens.Both,
 | 
			
		||||
                    ApiSecret = authenticationConfig.ApiSecret
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var authenticationNext = builder.Build();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
{
 | 
			
		||||
    public enum SupportedAuthenticationProviders
 | 
			
		||||
    {
 | 
			
		||||
        IdentityServer
 | 
			
		||||
        IdentityServer,
 | 
			
		||||
        Jwt
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,24 +2,52 @@
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    using Newtonsoft.Json;
 | 
			
		||||
 | 
			
		||||
    public class AuthenticationOptions
 | 
			
		||||
    {
 | 
			
		||||
        public AuthenticationOptions(string provider, string providerRootUrl, string apiName, bool requireHttps, List<string> allowedScopes, string apiSecret)
 | 
			
		||||
        public AuthenticationOptions(string provider, List<string> allowedScopes, IAuthenticationConfig config)
 | 
			
		||||
        {
 | 
			
		||||
            Provider = provider;
 | 
			
		||||
            ProviderRootUrl = providerRootUrl;
 | 
			
		||||
			ApiName = apiName;
 | 
			
		||||
            RequireHttps = requireHttps;
 | 
			
		||||
			AllowedScopes = allowedScopes;
 | 
			
		||||
            ApiSecret = apiSecret;
 | 
			
		||||
            AllowedScopes = allowedScopes;
 | 
			
		||||
            Config = config;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Provider { get; private set; }
 | 
			
		||||
        
 | 
			
		||||
        public List<string> AllowedScopes { get; private set; }
 | 
			
		||||
 | 
			
		||||
        public IAuthenticationConfig Config { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class IdentityServerConfig : IAuthenticationConfig
 | 
			
		||||
    {
 | 
			
		||||
        public IdentityServerConfig(string providerRootUrl, string apiName, bool requireHttps, string apiSecret)
 | 
			
		||||
        {
 | 
			
		||||
            ProviderRootUrl = providerRootUrl;
 | 
			
		||||
            ApiName = apiName;
 | 
			
		||||
            RequireHttps = requireHttps;
 | 
			
		||||
            ApiSecret = apiSecret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string ProviderRootUrl { get; private set; }
 | 
			
		||||
        public string ApiName { get; private set; }
 | 
			
		||||
        public string ApiSecret { get; private set; }
 | 
			
		||||
        public bool RequireHttps { get; private set; }
 | 
			
		||||
        public List<string> AllowedScopes { get; private set; }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class JwtConfig : IAuthenticationConfig
 | 
			
		||||
    {
 | 
			
		||||
        public JwtConfig(string authority, string audience)
 | 
			
		||||
        {
 | 
			
		||||
            Audience = audience;
 | 
			
		||||
            Authority = authority;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Audience { get; }
 | 
			
		||||
 | 
			
		||||
        public string Authority { get; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface IAuthenticationConfig {}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,51 +6,93 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        private string _provider;
 | 
			
		||||
        private string _providerRootUrl;
 | 
			
		||||
        private string _apiName;
 | 
			
		||||
        private string _apiSecret;
 | 
			
		||||
        private bool _requireHttps;
 | 
			
		||||
 | 
			
		||||
        private List<string> _allowedScopes;
 | 
			
		||||
 | 
			
		||||
        private IAuthenticationConfig _identityServerConfig;
 | 
			
		||||
 | 
			
		||||
        public AuthenticationOptionsBuilder WithProvider(string provider)
 | 
			
		||||
        {
 | 
			
		||||
            _provider = provider;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationOptionsBuilder WithProviderRootUrl(string providerRootUrl)
 | 
			
		||||
        {
 | 
			
		||||
            _providerRootUrl = providerRootUrl;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationOptionsBuilder WithApiName(string apiName)
 | 
			
		||||
        {
 | 
			
		||||
            _apiName = apiName;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationOptionsBuilder WithApiSecret(string apiSecret)
 | 
			
		||||
        {
 | 
			
		||||
            _apiSecret = apiSecret;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationOptionsBuilder WithRequireHttps(bool requireHttps)
 | 
			
		||||
        {
 | 
			
		||||
            _requireHttps = requireHttps;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
 | 
			
		||||
        {
 | 
			
		||||
            _allowedScopes = allowedScopes;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationOptionsBuilder WithConfig(IAuthenticationConfig config)
 | 
			
		||||
        {
 | 
			
		||||
            _identityServerConfig = config;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationOptions Build()
 | 
			
		||||
        {
 | 
			
		||||
            return new AuthenticationOptions(_provider, _providerRootUrl, _apiName, _requireHttps, _allowedScopes, _apiSecret);
 | 
			
		||||
            return new AuthenticationOptions(_provider, _allowedScopes, _identityServerConfig);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class IdentityServerConfigBuilder
 | 
			
		||||
    {
 | 
			
		||||
        private string _providerRootUrl;
 | 
			
		||||
        private string _apiName;
 | 
			
		||||
        private string _apiSecret;
 | 
			
		||||
        private bool _requireHttps;
 | 
			
		||||
        
 | 
			
		||||
        public IdentityServerConfigBuilder WithProviderRootUrl(string providerRootUrl)
 | 
			
		||||
        {
 | 
			
		||||
            _providerRootUrl = providerRootUrl;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IdentityServerConfigBuilder WithApiName(string apiName)
 | 
			
		||||
        {
 | 
			
		||||
            _apiName = apiName;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IdentityServerConfigBuilder WithApiSecret(string apiSecret)
 | 
			
		||||
        {
 | 
			
		||||
            _apiSecret = apiSecret;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IdentityServerConfigBuilder WithRequireHttps(bool requireHttps)
 | 
			
		||||
        {
 | 
			
		||||
            _requireHttps = requireHttps;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IdentityServerConfig Build()
 | 
			
		||||
        {
 | 
			
		||||
            return new IdentityServerConfig(_providerRootUrl, _apiName, _requireHttps, _apiSecret);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class JwtConfigBuilder
 | 
			
		||||
    {
 | 
			
		||||
        public string _authority;
 | 
			
		||||
 | 
			
		||||
        public string _audience;
 | 
			
		||||
 | 
			
		||||
        public JwtConfigBuilder WithAuthority(string authority)
 | 
			
		||||
        {
 | 
			
		||||
            _authority = authority;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public JwtConfigBuilder WithAudience(string audience)
 | 
			
		||||
        {
 | 
			
		||||
            _audience = audience;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public JwtConfig Build()
 | 
			
		||||
        {
 | 
			
		||||
            return new JwtConfig(_authority, _audience);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -7,14 +7,13 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
    {
 | 
			
		||||
        public AuthenticationOptions Create(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            var authenticationConfig = new ConfigCreator().Create(fileReRoute.AuthenticationOptions);
 | 
			
		||||
 | 
			
		||||
            return new AuthenticationOptionsBuilder()
 | 
			
		||||
                                        .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
 | 
			
		||||
                                        .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
 | 
			
		||||
                                        .WithApiName(fileReRoute.AuthenticationOptions?.ApiName)
 | 
			
		||||
                                        .WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
 | 
			
		||||
                                        .WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
 | 
			
		||||
                                        .WithApiSecret(fileReRoute.AuthenticationOptions?.ApiSecret)
 | 
			
		||||
                                        .Build();
 | 
			
		||||
        }
 | 
			
		||||
                .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
 | 
			
		||||
                .WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
 | 
			
		||||
                .WithConfig(authenticationConfig)
 | 
			
		||||
                .Build();
 | 
			
		||||
        } 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/Ocelot/Configuration/Creator/ConfigCreator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/Ocelot/Configuration/Creator/ConfigCreator.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
 | 
			
		||||
    public class ConfigCreator
 | 
			
		||||
    {
 | 
			
		||||
        public IAuthenticationConfig Create(FileAuthenticationOptions authenticationOptions)
 | 
			
		||||
        {
 | 
			
		||||
            if (authenticationOptions.Provider == "Jwt")
 | 
			
		||||
            {
 | 
			
		||||
                return CreateJwt(authenticationOptions);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return CreateIdentityServer(authenticationOptions);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private JwtConfig CreateJwt(FileAuthenticationOptions authenticationOptions)
 | 
			
		||||
        {
 | 
			
		||||
            return new JwtConfigBuilder()
 | 
			
		||||
                .WithAudience(authenticationOptions.JwtConfig?.Audience)
 | 
			
		||||
                .WithAuthority(authenticationOptions.JwtConfig?.Authority)
 | 
			
		||||
                .Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private IdentityServerConfig CreateIdentityServer(FileAuthenticationOptions authenticationOptions)
 | 
			
		||||
        {
 | 
			
		||||
            return new IdentityServerConfigBuilder()
 | 
			
		||||
                .WithApiName(authenticationOptions.IdentityServerConfig?.ApiName)
 | 
			
		||||
                .WithApiSecret(authenticationOptions.IdentityServerConfig?.ApiSecret)
 | 
			
		||||
                .WithProviderRootUrl(authenticationOptions.IdentityServerConfig?.ProviderRootUrl)
 | 
			
		||||
                .WithRequireHttps(authenticationOptions.IdentityServerConfig.RequireHttps).Build();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,14 +6,29 @@ namespace Ocelot.Configuration.File
 | 
			
		||||
    {
 | 
			
		||||
        public FileAuthenticationOptions()
 | 
			
		||||
        {
 | 
			
		||||
			AllowedScopes = new List<string>();
 | 
			
		||||
            AllowedScopes = new List<string>();
 | 
			
		||||
            IdentityServerConfig = new FileIdentityServerConfig();
 | 
			
		||||
            JwtConfig = new FileJwtConfig();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Provider { get; set; }
 | 
			
		||||
        public List<string> AllowedScopes { get; set; }
 | 
			
		||||
        public FileIdentityServerConfig IdentityServerConfig { get; set; }
 | 
			
		||||
        public FileJwtConfig JwtConfig { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class FileIdentityServerConfig
 | 
			
		||||
    {
 | 
			
		||||
        public string ProviderRootUrl { get; set; }
 | 
			
		||||
        public string ApiName { get; set; }
 | 
			
		||||
        public bool RequireHttps { get; set; }
 | 
			
		||||
        public List<string> AllowedScopes { get; set; }
 | 
			
		||||
        public string ApiSecret { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class FileJwtConfig
 | 
			
		||||
    {
 | 
			
		||||
        public string Authority { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string Audience { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,8 @@ using Ocelot.ServiceDiscovery;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Repository
 | 
			
		||||
{
 | 
			
		||||
    using Ocelot.AcceptanceTests;
 | 
			
		||||
 | 
			
		||||
    public class ConsulOcelotConfigurationRepository : IOcelotConfigurationRepository
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ConsulClient _consul;
 | 
			
		||||
@@ -48,7 +50,9 @@ namespace Ocelot.Configuration.Repository
 | 
			
		||||
 | 
			
		||||
            var json = Encoding.UTF8.GetString(bytes);
 | 
			
		||||
 | 
			
		||||
            var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
 | 
			
		||||
            var settings = new JsonSerializerSettings();
 | 
			
		||||
            settings.Converters.Add(new AuthenticationConfigConverter());
 | 
			
		||||
            var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json, settings);
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<IOcelotConfiguration>(consulConfig);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								src/Ocelot/JsonConverters/AuthenticationConfigConverter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/Ocelot/JsonConverters/AuthenticationConfigConverter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
using System;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    using Newtonsoft.Json.Linq;
 | 
			
		||||
    public class AuthenticationConfigConverter : JsonConverter
 | 
			
		||||
    {
 | 
			
		||||
        public override bool CanWrite => false;
 | 
			
		||||
 | 
			
		||||
        public override bool CanRead => true;
 | 
			
		||||
        
 | 
			
		||||
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            throw new InvalidOperationException("Use default serialization.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
 | 
			
		||||
        {
 | 
			
		||||
            var jsonObject = JObject.Load(reader);
 | 
			
		||||
            var setting = default(IAuthenticationConfig);
 | 
			
		||||
 | 
			
		||||
            if (jsonObject["Provider"] != null)
 | 
			
		||||
            {
 | 
			
		||||
                switch (jsonObject["Provider"].Value<string>())
 | 
			
		||||
                {
 | 
			
		||||
                    case "Jwt":
 | 
			
		||||
                        setting = new JwtConfig(
 | 
			
		||||
                            jsonObject["Authority"].Value<string>(),
 | 
			
		||||
                            jsonObject["Audience"].Value<string>());
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    default:
 | 
			
		||||
                        setting = new IdentityServerConfig(
 | 
			
		||||
                            jsonObject["ProviderRootUrl"].Value<string>(),
 | 
			
		||||
                            jsonObject["ApiName"].Value<string>(),
 | 
			
		||||
                            jsonObject["RequireHttps"].Value<bool>(),
 | 
			
		||||
                            jsonObject["ApiSecret"].Value<string>());
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                setting = new IdentityServerConfig(string.Empty, string.Empty, false, string.Empty);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            serializer.Populate(jsonObject.CreateReader(), setting);
 | 
			
		||||
            return setting;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool CanConvert(Type objectType)
 | 
			
		||||
        {
 | 
			
		||||
            return objectType == typeof(IAuthenticationConfig);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user