Я пытаюсь добавить уровень аутентификации в свой API с помощью OpenId
и OAuth2
, но когда я делаю вызов, передавая токен в заголовке, я продолжаю получать
Microsoft. IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: сообщение содержит ошибку: 'invalid_request', error_description: 'unauthorized_client', error_uri: 'error_uri is null'.
Я настроил AWS Cognito
, startup.cs
, и я могу успешно получить JWT token
от Swagger или Postman.
Вы видите, что что-то плохо настроено или отсутствует в моем startup.cs
?
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication(c =>
{
c.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
c.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
c.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(c =>
{
c.ResponseType = Configuration["Authentication:Cognito:ResponseType"];
c.MetadataAddress = Configuration["Authentication:Cognito:MetadataAddress"];
c.ClientId = Configuration["Authentication:Cognito:ClientId"];
c.Authority = "https://auth.myauthserver.com";
c.Scope.Add("myscope");
c.GetClaimsFromUserInfoEndpoint = true;
});
// Configure named auth policies that map directly to OAuth2.0 scopes
services.AddAuthorization(c =>
{
c.AddPolicy("myscope", p => p.RequireClaim("scope", "myscope"));
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "MyAPI", Version = "v1"
});
c.OperationFilter<AddAuthHeaderOperationFilter>();
c.AddSecurityDefinition("bearer", //Name the security scheme
new OpenApiSecurityScheme{
Flows = new OpenApiOAuthFlows()
{
ClientCredentials = new OpenApiOAuthFlow()
{
TokenUrl = new Uri("https://auth.myauthserver.com/oauth2/token"),
Scopes = new Dictionary<string, string>(){ {"myscope", "Access API"}},
AuthorizationUrl = new Uri("https://auth.myautherver.com/oauth2/authorize")
}
},
Type = SecuritySchemeType.OAuth2,
OpenIdConnectUrl = new Uri("https://cognito-idp-url.../.well-known/openid-configuration"),
BearerFormat = "JWT",
In = ParameterLocation.Header,
Scheme = "bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference{
Id = "Bearer",
Type = ReferenceType.SecurityScheme
},
OpenIdConnectUrl = new Uri("https://cognito-idp-url.../.well-known/openid-configuration")
},new List<string>(){"myscope"}
}
});
});
services.AddOptions();
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
}));
}
// 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();
else
app.UseHsts();
app.UseCors(policy =>
policy
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyOrigin()
.SetPreflightMaxAge(TimeSpan.FromDays(1))
);
app.UseCors("CorsPolicy");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
app.UseAuthentication();
app.UseSwagger();
app.UseSwaggerUI(c => {
c.SwaggerEndpoint($"v1/swagger.json", "MyAPI v1");
c.OAuth2RedirectUrl("https://auth.myauthserver.com/signin-oidc");
});
}
Контроллер имеет [Authorize]
и [Produces("application/json")]
атрибуты на нем.
Это AddAuthHeaderOperationFilter
:
public class AddAuthHeaderOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var isAuthorized = (context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any()
|| context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any())
&& !context.MethodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any(); // this excludes methods with AllowAnonymous attribute
if (!isAuthorized) return;
operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" });
operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" });
var jwtbearerScheme = new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearer" }
};
operation.Security = new List<OpenApiSecurityRequirement>
{
new OpenApiSecurityRequirement { [jwtbearerScheme] = new string []{} }
};
}
}
Это часть appsettings.json
:
"Authentication": {
"Cognito": {
"ClientId": "47...",
"IncludeErrorDetails": true,
"MetadataAddress": "https://cognito-idp-url.../.well-known/openid-configuration",
"RequireHttpsMetadata": false,
"ResponseType": "code",
"SaveToken": true,
"TokenValidationParameters": {
"ValidateIssuer": true
}
}
},
Cognito
настроен для приема потока OAuth для учетных данных клиента и выбрана разрешенная область аутентификации myscope
.
А это пример curl:
curl -X GET "https://localhost:5001/v1/MyController/2" -H "accept: application/json" -H "Authorization: Bearer eyJraWQiOiI2dGFPTW..."
Спасибо