Bearer authentication lets a client reuse a token obtained after login instead of sending credentials with every request. In this setup, an authentication server issues a token containing authorization information. The client sends it in the Authorization HTTP header on later requests, until the token expires. This gives a stateless API a way to recognize an authenticated caller across separate requests. section 9.1.2
Authentication establishes who the caller is; authorization decides what that caller may do. A bearer token carries information the server can use for authorization without repeating the login on every request. It is not the same as a session cookie: a cookie typically identifies server-stored session data, while the bearer token carries the relevant information itself. Protect the token from third-party access, because possession of it can enable access until it expires. section 9.1.2 section 9.6
To use a JWT bearer token while testing the board-game API:
- Configure Swagger with an HTTP security scheme named Bearer, using the Authorization header, the bearer scheme, and JWT as its format. Add a security requirement so SwaggerUI offers an Authorize button. section 9.3.1
- Call Account/Login with the test user's username and password, then copy the returned JWT into SwaggerUI's Authorize dialog. SwaggerUI can attach it to subsequent requests. section 9.3.1 section 9.3.3
- Call a protected endpoint before and after supplying the token. An endpoint marked [Authorize] returns 401 Unauthorized without authentication; /auth/test/1 returns 200 OK with a valid token when tested before its 300-second expiry. section 9.3.3
Listing 9.8 Program.cs file: Swagger’s bearer tokens setup
using Microsoft.OpenApi.Models; #1
// ... existing code
builder.Services.AddSwaggerGen(options => {
options.ParameterFilter<SortColumnFilter>();
options.ParameterFilter<SortOrderFilter>();
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme #2
{
In = ParameterLocation.Header,
Description = "Please enter token",
Name = "Authorization",
Type = SecuritySchemeType.Http,
BearerFormat = "JWT",
Scheme = "bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement #3
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type=ReferenceType.SecurityScheme,
Id="Bearer"
}
},
Array.Empty<string>()
}
});
});
The Swagger configuration shows how the Bearer security definition and global requirement expose token entry in SwaggerUI. section 9.3.1
A valid token does not automatically grant every permission. The basic [Authorize] test distinguishes anonymous from authenticated callers; finer access control can check roles or claims. For example, a board-game update through gRPC requires the Moderator role. Its controller passes the supplied token to the gRPC client in metadata as `Authorization: Bearer {token}`, while the service method carries `[Authorize(Roles = RoleNames.Moderator)]`. section 9.3.3 section 10.3.6
Listing 10.11 /Controllers/GrpcController.cs file: UpdateBoardGame method
using Grpc.Core; #1
// ... existing code
[HttpPost]
public async Task<BoardGameResponse> UpdateBoardGame(
string token, #2
int id,
string name)
{
var headers = new Metadata(); #3
headers.Add("Authorization", $"Bearer {token}"); #4
using var channel = GrpcChannel
.ForAddress("https://localhost:40443");
var client = new gRPC.Grpc.GrpcClient(channel);
var response = await client.UpdateBoardGameAsync(
new UpdateBoardGameRequest {
Id = id,
Name = name
},
headers); #5
return response;
}
The controller listing shows the exact Authorization metadata passed with the gRPC update request. section 10.3.6




