Validate JWT using swagger .net core 6 API - asp.net-core

I am trying to authorize a token using swagger. See the image below. My issue is when I type in an invalid token, I don't get any errors or anything.
Below is the API
[Authorize]
[HttpGet("GetUsers")]
public IEnumerable<CountryOutputDto> GetCountriesList()
{
return _countryAppService.GetCountries();
}
Below is are my settings
// Add Authencation
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "JWTToken_Auth_API", Version = "v1" });
c.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 1safsfsdfdfd\"",
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] {}
}
});
});
"JsonWebTokenKeys": {
"ValidateIssuerSigningKey": true,
"IssuerSigningKey": "64A63153-11C1-4919-9133-EFAF99A9B456",
"ValidateIssuer": false,
"ValidIssuer": "https://localhost:8100",
"ValidateAudience": false,
"ValidAudience": "https://localhost:8100",
"RequireExpirationTime": true,
"ValidateLifetime": true
}

Related

Can't authorize swagger through my Authorization Server using OIDC

I'm using Swashbuckle configured as
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v2", new OpenApiInfo { Title = "API", Version = "v2" });
c.AddSecurityDefinition("OpenId", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OpenIdConnect,
Name = "Authorization",
In = ParameterLocation.Header,
Scheme = "Bearer",
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri($"{authority}connect/authorize"),
TokenUrl = new Uri($"{authority}connect/token"),
Scopes = new Dictionary<string, string>
{
{
"openid", "openid"
},
{
"api", "api"
},
},
},
},
OpenIdConnectUrl = new Uri($"{authority}.well-known/openid-configuration"),
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "OpenId",
},
},
new List<string> { "api", "openid" }
},
});
});
And after that
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v2/swagger.json", "API v2");
c.OAuthUsePkce();
c.OAuthClientId(Configuration.GetRequiredSection("SwaggerOptions:ClientId").Value);
c.OAuthClientSecret(Configuration.GetRequiredSection("SwaggerOptions:ClientSecret").Value);
c.EnablePersistAuthorization();
c.OAuthScopes("api", "openid");
});
I see resulting swagger.json seems to be correct, as it declared at the docs
But something goes definitely wrong - I get CORS header 'Access-Control-Allow-Origin' missing reason for discovery request rejecting, simultaneously it returns a correct configuration with 200 ok
What have I missed?
Eventually, I was able to get this to work. I was misunderstanding which part does require CORS in this case. To fix that, I added my Swagger UI host to allowed hosts on auth server side and switch CORS on there. Now, all work fine!

Don't add Bearer verification

I have created an asp.net core project now, and I am making a swagger verification token, all of which are fine, but how to verify without adding the beginning of Bearer, what should I do?
enter image description here
If you want to omit the "Bearer" prefix tag, you can do this:
services.AddSwaggerGen(config =>
{
////Name the security scheme
config.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization",
Name = "Authorization",
In = ParameterLocation.Header,
// Type = SecuritySchemeType.ApiKey,
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat="JWT"
});
config.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
//The name of the previously defined security scheme.
Id = "Bearer"
}
},
new List<string>()
}
});
Note : If using SecuritySchemeType.ApiKey – token part should be
appended with ‘bearer’.
Note – If using SecuritySchemeType.Http – token need to be used
without “bearer”
Result:

Swagger JWT Authorization does not work in ASP.net core 3.1

I have this in my Startup.cs in the ConfigureServices:
services.ConfigureJwt(Configuration);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Backend.API", Version = "v1" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme (Example: 'Bearer 12345abcdef')",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
I have this in my Startup.cs in the Configure:
app.UseCors("EnableCors");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
This is my service extension:
public static void ConfigureJwt(this IServiceCollection services, IConfiguration configuration)
{
var settings = new JwtSettings();
settings.Key = configuration["JwtSettings:key"];
settings.Audience = configuration["JwtSettings:audience"];
settings.Issuer = configuration["JwtSettings:issuer"];
settings.MinutesToExpiration = Convert.ToInt32(
configuration["JwtSettings:minutesToExpiration"]);
services.AddSingleton(settings);
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "JwtBearer";
options.DefaultChallengeScheme = "JwtBearer";
})
.AddJwtBearer("JwtBearer", jwtBearerOptions =>
{
jwtBearerOptions.RequireHttpsMetadata = false;
jwtBearerOptions.SaveToken = true;
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = settings.Issuer,
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(settings.Key)),
ValidAudience = settings.Audience,
ClockSkew = TimeSpan.FromMinutes(
settings.MinutesToExpiration)
};
});
}
and in my Sagger UI login, this is the reply I get:
{
"userId": 1,
"userName": "user",
"firstName": "My FirstName",
"middleName": "A.",
"lastName": "My LastName",
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqdWFuIiwianRpIjoiNmQwNjQ4ZWMtOGI4YS00YTBkLTlmYmItZTliYWFmNzdmZjI2IiwiVXNlcklkIjoiMSIsIkZpcnN0TmFtZSI6Imp1YW4iLCJNaWRkbGVOYW1lIjoiQS4iLCJMYXN0TmFtZSI6IkRlbGEgQ3J1eiIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6WyJVc2VyIiwiQWRtaW4iXSwiZXhwIjoxNjA2OTc4MjcyLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo0NDM2NiIsImF1ZCI6IkdlbmVyYWxUZW1wbGF0ZSJ9.MMnu-suoae7U3QnXJTa9wI2xDUtdDJTtc63KWyd3bZM",
"isAuthenticated": true,
"claims": [
"User",
"Admin"
]
}
Why is it that I still get this error whenever I try to run an endpoint with [Authorize(Roles = "Admin")]
access-control-allow-origin: *
date: Thu03 Dec 2020 06:42:05 GMT
server: Microsoft-IIS/10.0
status: 401
www-authenticate: Bearer
x-powered-by: ASP.NET
This is the endpoint I am trying to run:
[HttpPost]
[Authorize(Roles = "Admin")]
public async Task<IActionResult> AddCategory(Category model)
{
var cm = new CategoryManager(context);
var result = await cm.Create(model);
if (result > 0)
{
return StatusCode(StatusCodes.Status201Created, model);
}
return StatusCode(StatusCodes.Status400BadRequest, model);
}
I was having this issue because I was just copy and pasting the "bearerToken" value in the Authorize of swagger. What I should do is copy the "bearerToken" value but add "Bearer " at the beginning.

Bearer token doesnot pass on swagger

I am trying to implement OAuth2 ClientCredentials flow on ASP.NET CORE 3.1. I follow guidelines on the official GitHub repo.
The problem is regarding getting bearer token on Swagger-UI. It doesn't pass automatically. I investigated the issue on Swashbuckle Github repo. There are some closed issues. There's no solution.
Below my implementation :
public static class SwaggerExtensions
{
public static IServiceCollection EnableSwagger(this IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Sample API", Version = "v1" });
c.AddSecurityDefinition("oauth2",
new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
ClientCredentials = new OpenApiOAuthFlow
{
TokenUrl = new Uri("/api/auth/token", UriKind.Relative),
Scopes = new Dictionary<string, string>
{
{ "readAccess", "Access read operations" },
{ "writeAccess", "Access write operations" }
},
}
},
Name = "Authorization",
In = ParameterLocation.Header,
Scheme = "Bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }, Name = "oauth2"
},
new[] { "readAccess", "writeAccess" }
}
});
c.OperationFilter<OAuth2OperationFilter>();
});
return services;
}
public class AuthenticationAttribute : Attribute, IAsyncAuthorizationFilter
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
bool isAnonymousAllowed = context.Filters.Any(f => f.GetType() == typeof(AllowAnonymousFilter));
if (isAnonymousAllowed)
{
return;
}
if (!context.HttpContext.Request.Headers.TryGetValue("Authorization", out var authHeaderValue))
{
throw new UnauthorizedAccessException("A valid key must be supplied");
}
string authHeader = authHeaderValue.ToString();
if (string.IsNullOrEmpty(authHeader))
....
}
}
After creating an access_token, I cannot get this token on another controller on Swagger-UI.
Swashbuckle.AspNetCore version -> 5.5.1
Swashbuckle.AspNetCore.Swagger -> 5.5.1

Curl appending authorisation header but controller still 401

I am using the swagger gen ui and I am using the following settings and following this GitHub resource.
This seems to be a known issue with swagger according to GitHub, I am using a jwt barrer based token. https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1425
I have setup my swagger gen as follows
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "App Manager - Running Buddies", Version = "v1" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
Description = "JWT Authorization header using the Bearer scheme.",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
}, new List<string>()
}
});
});
curl -X GET "https://localhost:44396/api/BmiInformations" -H "accept:
text/plain" -H "Authorization:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTAxOTMyNzQsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0Mzk2LyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0Mzk2LyJ9.cbePeT9RJprvTWyQECiUCaoqjc25eFKtf7jh5DwOnU0"
But Still I am getting 401 unauthorised I am using a JWT based token that is valid.
private string BuildToken(LoginModel login) {
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JwtToken:SecretKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
JwtSecurityToken token;
token = new JwtSecurityToken(_config["JwtToken:Issuer"],
_config["JwtToken:Issuer"], expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
private UserModel Authenticate(LoginModel login) {
UserModel user = null;
//var result = await _signInManager.PasswordSignInAsync(, lockoutOnFailure: false);
if (login.Username == "mario" && login.Password == "secret") {
user = new UserModel { UserName = "Mario Rossi", Email = "mario.rossi#domain.com" };
}
return user;
}
This is how am building up my filter.
public class AddAuthHeaderOperationFilter : IOperationFilter {
public void Apply(OpenApiOperation operation, OperationFilterContext context) {
if (operation.Security == null)
operation.Security = new List<OpenApiSecurityRequirement>();
var scheme = new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearer" } };
operation.Security.Add(new OpenApiSecurityRequirement {
[scheme] = new List<string>()
});
}
I have added to after my barrer bit. But its still not showing the word barrer
services.AddDbContext<AppManagerDL.AppManagerDBContext>
(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "App Manager - Running Buddies", Version = "v1" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme.",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "bearer"
});
c.OperationFilter<AddAuthHeaderOperationFilter>();
Edit 4
Ok So now I have it showing Barrer correctly in the curl but its now saying the signature is invalid even though its getting the correct one from my appsettings.
curl -X GET "https://localhost:44396/api/BmiInformations" -H "accept:
text/plain" -H "Authorization: Bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTAxOTc0MTcsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0Mzk2LyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0Mzk2LyJ9.fLWxG1bRX6yCTqFe8XZbgL6Lh1RNcmVFX-636ZvqhNg"
My Settings in start up as as follows.
public void ConfigureServices(IServiceCollection services) {
services.AddDbContext<AppManagerDL.AppManagerDBContext>
(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo { Title = "App Manager - Running Buddies", Version = "v1" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
Description = "JWT Authorization header using the Bearer scheme.",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
new OpenApiSecurityScheme{
Reference = new OpenApiReference{
Id = "Bearer", //The name of the previously defined security scheme.
Type = ReferenceType.SecurityScheme
}
},new List<string>()
}
});
The Exact error I am now getting is.
date: Sat, 23 May 2020 01:04:11 GMT server: Microsoft-IIS/10.0
status: 401 www-authenticate: Bearer error="invalid_token",
error_description="The signature is invalid" x-powered-by: ASP.NET
Try replacing your current security definition with this :
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme.",
Name = "Authorization",
In = ParameterLocation.Header,
Scheme = "bearer",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT"
});