mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	hacky auth working
This commit is contained in:
		
							
								
								
									
										22
									
								
								src/Ocelot/Configuration/Authentication/HashMatcher.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/Ocelot/Configuration/Authentication/HashMatcher.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
using System;
 | 
			
		||||
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Authentication
 | 
			
		||||
{
 | 
			
		||||
    public class HashMatcher : IHashMatcher
 | 
			
		||||
    {
 | 
			
		||||
        public bool Match(string password, string salt, string hash)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] s = Convert.FromBase64String(salt);
 | 
			
		||||
 | 
			
		||||
            string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
 | 
			
		||||
                password: password,
 | 
			
		||||
                salt: s,
 | 
			
		||||
                prf: KeyDerivationPrf.HMACSHA256,
 | 
			
		||||
                iterationCount: 10000,
 | 
			
		||||
                numBytesRequested: 256 / 8));
 | 
			
		||||
 | 
			
		||||
                return hashed == hash;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								src/Ocelot/Configuration/Authentication/IHashMatcher.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/Ocelot/Configuration/Authentication/IHashMatcher.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
namespace Ocelot.Configuration.Authentication
 | 
			
		||||
{
 | 
			
		||||
    public interface IHashMatcher
 | 
			
		||||
    {
 | 
			
		||||
        bool Match(string password, string salt, string hash);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,53 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using IdentityServer4.Models;
 | 
			
		||||
using IdentityServer4.Validation;
 | 
			
		||||
using Ocelot.Configuration.Provider;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Authentication
 | 
			
		||||
{
 | 
			
		||||
    public class OcelotResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IHashMatcher _matcher;
 | 
			
		||||
        private readonly IIdentityServerConfiguration _identityServerConfiguration;
 | 
			
		||||
 | 
			
		||||
        public OcelotResourceOwnerPasswordValidator(IHashMatcher matcher, IIdentityServerConfiguration identityServerConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            _identityServerConfiguration = identityServerConfiguration;
 | 
			
		||||
            _matcher = matcher;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var user = _identityServerConfiguration.Users.FirstOrDefault(u => u.UserName == context.UserName);
 | 
			
		||||
 | 
			
		||||
                if(user == null)
 | 
			
		||||
                {
 | 
			
		||||
                    context.Result = new GrantValidationResult(
 | 
			
		||||
                            TokenRequestErrors.InvalidGrant,
 | 
			
		||||
                            "invalid custom credential");
 | 
			
		||||
                }
 | 
			
		||||
                else if(_matcher.Match(context.Password, user.Salt, user.Hash))
 | 
			
		||||
                {
 | 
			
		||||
                    context.Result = new GrantValidationResult(
 | 
			
		||||
                        subject: "admin",
 | 
			
		||||
                        authenticationMethod: "custom");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    context.Result = new GrantValidationResult(
 | 
			
		||||
                        TokenRequestErrors.InvalidGrant,
 | 
			
		||||
                        "invalid custom credential");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch(Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                Console.WriteLine(ex);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using IdentityServer4.AccessTokenValidation;
 | 
			
		||||
using IdentityServer4.Models;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Provider
 | 
			
		||||
{
 | 
			
		||||
    public interface IIdentityServerConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        string ApiName { get;  }
 | 
			
		||||
        bool RequireHttps { get;  }
 | 
			
		||||
        List<string> AllowedScopes { get;  }
 | 
			
		||||
        SupportedTokens SupportedTokens { get;  }
 | 
			
		||||
        string ApiSecret { get;  }
 | 
			
		||||
        string Description {get;}
 | 
			
		||||
        bool Enabled {get;}
 | 
			
		||||
        IEnumerable<string>  AllowedGrantTypes {get;}
 | 
			
		||||
        AccessTokenType AccessTokenType {get;}
 | 
			
		||||
        bool RequireClientSecret {get;}
 | 
			
		||||
        List<User> Users {get;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,49 +1,12 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using IdentityServer4.AccessTokenValidation;
 | 
			
		||||
using IdentityServer4.Models;
 | 
			
		||||
using IdentityServer4.Test;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Provider
 | 
			
		||||
{
 | 
			
		||||
    public class HardCodedIdentityServerConfigurationProvider : IIdentityServerConfigurationProvider
 | 
			
		||||
    {
 | 
			
		||||
        public IdentityServerConfiguration Get()
 | 
			
		||||
        {
 | 
			
		||||
            var url = "";
 | 
			
		||||
            return new IdentityServerConfiguration(
 | 
			
		||||
                url,
 | 
			
		||||
                "admin",
 | 
			
		||||
                false,
 | 
			
		||||
                SupportedTokens.Both,
 | 
			
		||||
                "secret",
 | 
			
		||||
                new List<string> {"admin", "openid", "offline_access"},
 | 
			
		||||
                "Ocelot Administration",
 | 
			
		||||
                true,
 | 
			
		||||
                GrantTypes.ResourceOwnerPassword,
 | 
			
		||||
                AccessTokenType.Jwt,
 | 
			
		||||
                false,
 | 
			
		||||
                new List<TestUser> {
 | 
			
		||||
                        new TestUser
 | 
			
		||||
                        { 
 | 
			
		||||
                            Username = "admin",
 | 
			
		||||
                            Password = "admin",
 | 
			
		||||
                            SubjectId = "admin",
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface IIdentityServerConfigurationProvider
 | 
			
		||||
    {
 | 
			
		||||
        IdentityServerConfiguration Get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class IdentityServerConfiguration
 | 
			
		||||
    public class IdentityServerConfiguration : IIdentityServerConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        public IdentityServerConfiguration(
 | 
			
		||||
            string identityServerUrl, 
 | 
			
		||||
            string apiName, 
 | 
			
		||||
            bool requireHttps, 
 | 
			
		||||
            SupportedTokens supportedTokens, 
 | 
			
		||||
@@ -54,9 +17,8 @@ namespace Ocelot.Configuration.Provider
 | 
			
		||||
            IEnumerable<string>  grantType,
 | 
			
		||||
            AccessTokenType accessTokenType,
 | 
			
		||||
            bool requireClientSecret,
 | 
			
		||||
            List<TestUser> users)
 | 
			
		||||
            List<User> users)
 | 
			
		||||
        {
 | 
			
		||||
            IdentityServerUrl = identityServerUrl;
 | 
			
		||||
            ApiName = apiName;
 | 
			
		||||
            RequireHttps = requireHttps;
 | 
			
		||||
            SupportedTokens = supportedTokens;
 | 
			
		||||
@@ -70,7 +32,6 @@ namespace Ocelot.Configuration.Provider
 | 
			
		||||
            Users = users;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string IdentityServerUrl { get; private set; }
 | 
			
		||||
        public string ApiName { get; private set; }
 | 
			
		||||
        public bool RequireHttps { get; private set; }
 | 
			
		||||
        public List<string> AllowedScopes { get; private set; }
 | 
			
		||||
@@ -80,7 +41,7 @@ namespace Ocelot.Configuration.Provider
 | 
			
		||||
        public bool Enabled {get;private set;}
 | 
			
		||||
        public IEnumerable<string>  AllowedGrantTypes {get;private set;}
 | 
			
		||||
        public AccessTokenType AccessTokenType {get;private set;}
 | 
			
		||||
        public bool RequireClientSecret = false;
 | 
			
		||||
        public List<TestUser> Users {get;private set;}
 | 
			
		||||
        public bool RequireClientSecret {get;private set;}
 | 
			
		||||
        public List<User> Users {get;private set;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/Ocelot/Configuration/Provider/User.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/Ocelot/Configuration/Provider/User.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
namespace Ocelot.Configuration.Provider
 | 
			
		||||
{
 | 
			
		||||
    public class User
 | 
			
		||||
    {
 | 
			
		||||
        public User(string subject, string userName, string hash, string salt)
 | 
			
		||||
        {
 | 
			
		||||
            Subject = subject;
 | 
			
		||||
            UserName = userName;
 | 
			
		||||
            Hash = hash;
 | 
			
		||||
            Salt = salt;
 | 
			
		||||
        }
 | 
			
		||||
        public string Subject { get; private set; }
 | 
			
		||||
        public string UserName { get; private set; }
 | 
			
		||||
        public string Hash { get; private set; }
 | 
			
		||||
        public string Salt { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -14,6 +14,7 @@ using Ocelot.Authentication.Handler.Factory;
 | 
			
		||||
using Ocelot.Authorisation;
 | 
			
		||||
using Ocelot.Cache;
 | 
			
		||||
using Ocelot.Claims;
 | 
			
		||||
using Ocelot.Configuration.Authentication;
 | 
			
		||||
using Ocelot.Configuration.Creator;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Configuration.Parser;
 | 
			
		||||
@@ -41,7 +42,6 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
{
 | 
			
		||||
    public static class ServiceCollectionExtensions
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddOcelotOutputCaching(this IServiceCollection services, Action<ConfigurationBuilderCachePart> settings)
 | 
			
		||||
        {
 | 
			
		||||
            var cacheManagerOutputCache = CacheFactory.Build<HttpResponseMessage>("OcelotOutputCache", settings);
 | 
			
		||||
@@ -51,24 +51,23 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
        public static IServiceCollection AddOcelotFileConfiguration(this IServiceCollection services, IConfigurationRoot configurationRoot)
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddOcelot(this IServiceCollection services, IConfigurationRoot configurationRoot)
 | 
			
		||||
        {
 | 
			
		||||
            return AddOcelot(services, configurationRoot, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddOcelot(this IServiceCollection services, IConfigurationRoot configurationRoot, IIdentityServerConfiguration identityServerConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            services.Configure<FileConfiguration>(configurationRoot);
 | 
			
		||||
            services.AddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
 | 
			
		||||
            services.AddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
 | 
			
		||||
            services.AddSingleton<IConfigurationValidator, FileConfigurationValidator>();
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddOcelot(this IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            return AddOcelot(services, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddOcelot(this IServiceCollection services, IdentityServerConfiguration identityServerConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            
 | 
			
		||||
            if(identityServerConfiguration != null)
 | 
			
		||||
            {
 | 
			
		||||
                services.AddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
 | 
			
		||||
                services.AddSingleton<IHashMatcher, HashMatcher>();
 | 
			
		||||
                services.AddIdentityServer()
 | 
			
		||||
                    .AddTemporarySigningCredential()
 | 
			
		||||
                    .AddInMemoryApiResources(new List<ApiResource>
 | 
			
		||||
@@ -101,8 +100,7 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
                            Enabled = identityServerConfiguration.Enabled,
 | 
			
		||||
                            RequireClientSecret = identityServerConfiguration.RequireClientSecret
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                    .AddTestUsers(identityServerConfiguration.Users);
 | 
			
		||||
                    }).AddResourceOwnerValidator<OcelotResourceOwnerPasswordValidator>();
 | 
			
		||||
            }
 | 
			
		||||
        
 | 
			
		||||
            services.AddMvcCore()
 | 
			
		||||
 
 | 
			
		||||
@@ -37,21 +37,7 @@ namespace Ocelot.Middleware
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            await builder.UseOcelot(new OcelotMiddlewareConfiguration(), null);
 | 
			
		||||
 | 
			
		||||
            return builder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder,IdentityServerConfiguration identityServerConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            await builder.UseOcelot(new OcelotMiddlewareConfiguration(), identityServerConfiguration);
 | 
			
		||||
 | 
			
		||||
            return builder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder,OcelotMiddlewareConfiguration middlewareConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            await builder.UseOcelot(middlewareConfiguration, null);
 | 
			
		||||
            await builder.UseOcelot(new OcelotMiddlewareConfiguration());
 | 
			
		||||
 | 
			
		||||
            return builder;
 | 
			
		||||
        }
 | 
			
		||||
@@ -62,9 +48,9 @@ namespace Ocelot.Middleware
 | 
			
		||||
        /// <param name="builder"></param>
 | 
			
		||||
        /// <param name="middlewareConfiguration"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, OcelotMiddlewareConfiguration middlewareConfiguration, IdentityServerConfiguration identityServerConfiguration)
 | 
			
		||||
        public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder,       OcelotMiddlewareConfiguration middlewareConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            await CreateAdministrationArea(builder, identityServerConfiguration);
 | 
			
		||||
            await CreateAdministrationArea(builder);
 | 
			
		||||
 | 
			
		||||
            // This is registered to catch any global exceptions that are not handled
 | 
			
		||||
            builder.UseExceptionHandlerMiddleware();
 | 
			
		||||
@@ -168,10 +154,12 @@ namespace Ocelot.Middleware
 | 
			
		||||
            return ocelotConfiguration.Data;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static async Task CreateAdministrationArea(IApplicationBuilder builder, IdentityServerConfiguration identityServerConfiguration)
 | 
			
		||||
        private static async Task CreateAdministrationArea(IApplicationBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = await CreateConfiguration(builder);
 | 
			
		||||
 | 
			
		||||
            var identityServerConfiguration = (IIdentityServerConfiguration)builder.ApplicationServices.GetService(typeof(IIdentityServerConfiguration));
 | 
			
		||||
 | 
			
		||||
            if(!string.IsNullOrEmpty(configuration.AdministrationPath) && identityServerConfiguration != null)
 | 
			
		||||
            {
 | 
			
		||||
                var webHostBuilder = (IWebHostBuilder)builder.ApplicationServices.GetService(typeof(IWebHostBuilder));
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,8 @@
 | 
			
		||||
        "CacheManager.Microsoft.Extensions.Logging": "0.9.2",
 | 
			
		||||
        "Consul": "0.7.2.1",
 | 
			
		||||
        "Polly": "5.0.3",
 | 
			
		||||
        "IdentityServer4": "1.0.1"
 | 
			
		||||
        "IdentityServer4": "1.0.1",
 | 
			
		||||
        "Microsoft.AspNetCore.Cryptography.KeyDerivation": "1.1.0"
 | 
			
		||||
    },
 | 
			
		||||
  "runtimes": {
 | 
			
		||||
    "win10-x64": {},
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user