【问题标题】:How to create Customtom Authorize Attribute in .net core web api 3.1?如何在 .net core web api 3.1 中创建 Customtom 授权属性?
【发布时间】:2020-10-27 14:29:27
【问题描述】:

我有两个 api 项目

  1. ConsumerApi

  2. MasterApi

MasterApi 负责创建和验证令牌。我需要保护 ConsumerApi 资源。这就是为什么我有一个带有 login 方法的 LoginController

首先用户点击这个方法并传递他们的用户名和密码。 ConsumerApi 然后调用 MasterApi 获取令牌并将令牌返回给 User。然后 UserAuthorization 标头中使用此 JWT 令牌作为 Bearer retrive_jwt_token 来调用 ConsumerApi 受保护的资源。要使用 MasterApi 验证令牌,我在 ConsumerApi 中有一个 CustomAuthorizeAttribute,我在此项目控制器或方法上面提到了它。

下面是我的 CustomAuthorizeAttribute

public class ExternalAuthorization : AuthorizeAttribute, IAuthorizationFilter
    {
        private readonly HttpClient _httpClient;
        public ExternalAuthorization()
        {
            _httpClient = new HttpClient();
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            if (context.HttpContext.Request.Headers.TryGetValue("Authorization", out var authHeader))
            {
                var accessToken = authHeader.ToString().Split(' ')[1];
                var response = _httpClient.GetAsync(
                    $"https://localhost:44359/api/oauth/validate?token={accessToken}").Result;
                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    context.Result = new UnauthorizedResult();
                }
            }
        }
    }

我在我的 ConsumerApi 控制器方法之一中使用它,如下所示:

        [ExternalAuthorization]
        [HttpGet("getall")]
        public IEnumerable<WeatherForecast> GetAll()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }

但是当我调用这个方法时,我遇到了异常

System.InvalidOperationException: Endpoint ConsumerApiClient.Controllers.WeatherForecastController.GetAll (ConsumerApi) contains authorization metadata, but a middleware was not found that supports authorization.
Configure your application startup by adding app.UseAuthorization() inside the call to Configure(..) in the application startup code. The call to app.UseAuthorization() must appear between app.UseRouting() and app.UseEndpoints(...).
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.ThrowMissingAuthMiddlewareException(Endpoint endpoint)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,bn;q=0.7
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6InVzZXJfaWQiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJyZWd1bGFyIiwibmJmIjoxNTk0MTE1MDg4LCJleHAiOjE1OTQyMDE0ODgsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0MzU5LyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0MzU5LyJ9.mOEaM_IuQ0w_CKGcMHXACXCdCOebzdc19ArSeOOgxek
Cache-Control: no-cache
Connection: close
Host: localhost:44326
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
dnt: 1
x-postman-interceptor-id: 9dc8740c-6d4d-eb6b-4376-3eefdb355cb8
postman-token: 3191c452-708a-efd0-237a-0c343eb16bd6
sec-fetch-site: none
sec-fetch-mode: cors
sec-fetch-dest: empty

我是否需要在 StartUp.cs 中添加它,如果需要,我该怎么做?

【问题讨论】:

    标签: c# api authorization asp.net-core-webapi custom-authentication


    【解决方案1】:

    根据例外情况,app.UseAuthorization 应该介于app.UseRouting()app.UseEndpoints(...) 之间,如下所示:

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller}/{action=Index}/{id?}");
    });
    

    【讨论】:

    • 是的,我也添加了这些但仍然出现错误,它说找不到身份验证架构
    猜你喜欢
    • 2020-09-27
    • 2020-11-13
    • 2021-02-01
    • 2020-12-03
    • 2020-06-22
    • 2018-01-29
    • 2020-08-02
    • 1970-01-01
    • 2020-02-11
    相关资源
    最近更新 更多