简体   繁体   English

ASP.NET 核心 API 使用 JWT 不记名令牌进行身份验证

[英]ASP.NET Core API authenticate using JWT bearer tokens

I have a new API I would like to authenticate using an external security provider (auth server).我有一个新的 API 我想使用外部安全提供程序(身份验证服务器)进行身份验证。 I have the following code, however I get an error when call my authenticated action with everything set up.我有以下代码,但是在设置完所有内容后调用经过身份验证的操作时出现错误。

Startup.cs:启动.cs:

public async void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddScoped<ITemperatureLoggerRepository<ConsolidatedTables>, TemperatureLoggerRepository>();

            services.AddDbContext<TemperatureLoggerContext>(options => options.UseSqlServer(Configuration["Data:ConnectionString:TemperatureLoggerDB"]));

            services.AddSwaggerGen(swagger =>
            {
                swagger.SwaggerDoc("v1", new OpenApiInfo { Title = "Temperature Logger API", Version = "Version 1" });
                swagger.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                {
                    Name = "Authorization",
                    Type = SecuritySchemeType.ApiKey,
                    Scheme = "Bearer",
                    BearerFormat = "JWT",
                    In = ParameterLocation.Header,
                    Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
                });
                swagger.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                          new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference
                                {
                                    Type = ReferenceType.SecurityScheme,
                                    Id = "Bearer"
                                }
                            },
                            new string[] {}
                    }
                });
            });

            Response<List<Client>> response = await services.AddAuthServer(Configuration);

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            }).AddJwtBearer(options =>
            {
                var signingKeys = new List<SymmetricSecurityKey>();
                foreach (var client in response.Data)
                {
                    signingKeys.Add(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(client.Base64Secret)));
                }

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = false,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["Jwt:Issuer"],
                    ValidAudience = Configuration["Jwt:Issuer"],
                    IssuerSigningKeys = signingKeys
                };
            }).AddOAuthValidation();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.UseAuthentication();
            
            app.UseSwagger();

            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "Temperature Logger API");
            });
        }

AuthServer.cs that calls a list of clients that will be allowed to access API: AuthServer.cs 调用将被允许访问 API 的客户端列表:

public static async Task<Response<List<Client>>> AddAuthServer(this IServiceCollection collection, IConfiguration config)
        {
            var clientHandler = new HttpClientHandler
            {
                CookieContainer = new CookieContainer(),
                UseCookies = true
            };

            using (var httpClient = new HttpClient(clientHandler))
            {
                HttpContent content = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("grant_type", "client_credentials"),
                    new KeyValuePair<string, string>("client_id", config["Jwt:ClientId"]),
                    new KeyValuePair<string, string>("client_secret", config["Jwt:ClientSecret"])
                });
                httpClient.BaseAddress = new Uri(config["Jwt:Issuer"]);
                var responseMessage = await httpClient.PostAsync(config["Jwt:Issuer"] + "oauth2/token", content);
                var result = await responseMessage.Content.ReadAsStringAsync();
                _tokenResponse = JsonConvert.DeserializeObject<Token>(result);
            }

            var clientHandler2 = new HttpClientHandler
            {
                CookieContainer = new CookieContainer(),
                UseCookies = true
            };
            using (var httpClient2 = new HttpClient(clientHandler2))
            {
                httpClient2.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _tokenResponse.access_token);
                using (var response = await httpClient2.GetAsync(config["Jwt:Issuer"] + "api/Client/GetIdKeys"))
                {
                    if (!response.IsSuccessStatusCode) throw new Exception(response.StatusCode.ToString());
                    //string clientsResponse = await response.Content.ReadAsStringAsync();
                    return await response.Content.ReadAsAsync<Response<List<Client>>>();
                }
            }
        }

HomeController.cs (Authenticated Action): HomeController.cs(经过身份验证的操作):

[Produces("application/json")]
    [Route("api/home")]
    [ApiController]
    [Authorize]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
        public IActionResult Index()
        {
            return Ok("Welcome to our Protected World!");
        }
    }

RESULT:结果: 在此处输入图像描述

Please asssist how I can get this working.请协助我如何使其正常工作。 The API also has its on ClientId and ClientSecret assigned to it. API 还分配了其 on ClientId 和 ClientSecret。

I managed to figure out the problem and it was pretty straight forward and I missed it.我设法找出了问题所在,这很简单,但我错过了。 It really had nothing to do with getting a list of my audience or any extra configuration.这与获取我的观众名单或任何额外配置无关。 I needed to decode the keys I got from my store:我需要解码从商店获得的密钥:

var signingKeys = new List<SymmetricSecurityKey>();
foreach (var client in response.Data)
{
   signingKeys.Add(new SymmetricSecurityKey(Base64UrlEncoder.DecodeBytes(/***base64Secret***/)));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Microsoft Graph令牌通过Jwt Bearer令牌保护ASP.NET Core Web API - Using Microsoft Graph token to secure ASP.NET Core Web API with Jwt Bearer tokens 如何为 JwtBearer 和 System.IdentityModel.Tokens.Jwt 在 asp.net 内核中自定义承载 header 关键字? - How to customize bearer header keyword in asp.net core for JwtBearer and System.IdentityModel.Tokens.Jwt? 使用来自 Azure AD 的承载令牌保护 ASP.Net Core 3.1 API - Secure ASP.Net Core 3.1 API with Bearer Tokens from Azure AD ASP.NET Core 2.0 IAuthorizationService和过期的承载令牌 - ASP.NET Core 2.0 IAuthorizationService And Expired Bearer Tokens ASP.Net Core 3.0 JWT Bearer Token 没有可用的 SecurityTokenValidator - ASP.Net Core 3.0 JWT Bearer Token No SecurityTokenValidator available 在 ASP.NET Core 中的 Swagger 中使用 JWT(授权:承载) - Use JWT (Authorization: Bearer) in Swagger in ASP.NET Core ASP.NET Core JWT 不记名令牌自定义验证 - ASP.NET Core JWT Bearer Token Custom Validation 使用依赖注入替换ASP.NET Core中的JWT Bearer Options - Using dependency injection to replace JWT Bearer Options in ASP.NET Core JWT不记名令牌授权不起作用asp net core web api - JWT bearer token Authorization not working asp net core web api 如何在asp.net core web api中实现JWT Refresh Tokens(没有第三方)? - How to implement JWT Refresh Tokens in asp.net core web api (no 3rd party)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM