dotnet core 3.0 WebApi,applicationPart和授权

时间:2019-10-15 20:15:31

标签: c# .net-core

我们有一个模块化应用程序,这意味着我们的api控制器会在启动过程中加载。我们像这样将控制器加载到applicationPart中:

services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
            .ConfigureApplicationPartManager(applicationPartManager =>
            {
                foreach (var module in _modules)
                {
                    var apiControllerAssemblies = module.GetApiControllerAssemblies();

                    foreach (var apiControllerAssembly in apiControllerAssemblies)
                        applicationPartManager.ApplicationParts.Add(new AssemblyPart(apiControllerAssembly));
                }
            });

我们想通过基本身份验证来保护我们的api。我创建了这样的中间件:

 public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
    {
        public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, 
                                          ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
        {
        }

        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            if (!Request.Headers.ContainsKey("Authorization"))
                return AuthenticateResult.Fail("Missing Authorization 
                                                Header");
            //More to come
        }
    }

中间件是这样注册在startup.cs中的:

services.AddAuthentication("Basic")
             .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("Basic", null);

访问localhost:将始终触发HandleAuthenticateAsync方法。但是,当我尝试访问localhost:/ user / users端点时,该方法永远不会到达断点,并且始终会导致HTTP 401未经授权。控制器本身带有Authorize属性标记。

任何想法哪里出了问题?我应该从哪里开始寻找解决方案的任何提示?

谢谢!

1 个答案:

答案 0 :(得分:1)

不确定这是否有帮助,但是当我必须执行身份验证时,这就是我所做的。

a。声明一个扩展AuthenticationSchemeOptions

的类
    public class CustomAuthOptions: AuthenticationSchemeOptions
    {
    }

b。声明一个实现AuthenticationHandler<TOptions>

的类
    internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
    {
        IHttpContextAccessor _httpContextAccessor;
        IUser _user;

        public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, 
            IHttpContextAccessor httpContextAccessor, IUser user) : base(options, logger, encoder, clock)
        {
            _httpContextAccessor = httpContextAccessor;
            _user = user;
        }

        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            //logic to authenticate
        }

        protected override Task HandleChallengeAsync(AuthenticationProperties properties)
        {
            //more code
        }
   }

c。将扩展方法添加到AuthenticationBuilder

        public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder,
            Action<CustomAuthOptions> config)
        {
            return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("CheckInDB", "CheckInDB", config);
        }
d。最后在Startup.cs

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = "CheckInDB";
                options.DefaultChallengeScheme = "CheckInDB";
            }).AddCustomAuth(c => { });

这可能比需要的更多,但是几个月前,当我在同一条船上时,我花了很多天将所有这些拼凑在一起。