The sample is .net 6. Why don’t you get it working before trying to change to the program to the optional min api
How to implement JWT autentication in ASP Core Net 6 and gRPC?
I am trying to learn how to use JWT authentication in ASP Core Net 6 and gRPC. I am following this example.
The problem is that they are using the StartUp.cs file, that doesn't exist in the ASP Core Net 6. So I am trying some options.
I have done some tries, but I get the error about mismatch certificate.
So I would like to know if there any documentation about how to use this kind of authentication in Net 6 or if someone could help me how to do it.
This is my code in the service:
program.cs
using GestorOrdenadores.Service.Grpc.DotNet.Services;
using ProtoBuf.Grpc.Server;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authentication.JwtBearer;
var builder = WebApplication.CreateBuilder(args);
//Se configura kestrel, donde se puede indicar los protocolos, certificados, puertos de escucha... etc.
builder.WebHost.ConfigureKestrel((context, options) =>
{
options.ListenAnyIP(5004, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
listenOptions.UseHttps();
});
});
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = false,
ValidateActor = false,
ValidateLifetime = true,
IssuerSigningKey = GestorOrdenadores.Service.Grpc.DotNet.Autenticacion.SecurityKey
};
});
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
// Add services to the container.
builder.Services.AddCodeFirstGrpc();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
//Configuración para utilizar JWT (un token), para la autenticación de la aplicación.
app.MapGet("/", context =>
{
GestorOrdenadores.Service.Grpc.DotNet.Autenticacion miAutenticador = new GestorOrdenadores.Service.Grpc.DotNet.Autenticacion();
return context.Response.WriteAsync(miAutenticador.GenerateJwtToken(context.Request.Query["name"]));
});
app.Run();
Authentication auxiliar class:
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
namespace GestorOrdenadores.Service.Grpc.DotNet
{
internal class Autenticacion
{
private readonly JwtSecurityTokenHandler JwtTokenHandler;
internal static readonly SymmetricSecurityKey SecurityKey = new SymmetricSecurityKey(Guid.NewGuid().ToByteArray());
public Autenticacion()
{
JwtTokenHandler = new JwtSecurityTokenHandler();
}
internal string GenerateJwtToken(string paramName)
{
if (string.IsNullOrEmpty(paramName))
{
throw new InvalidOperationException("Name is not specified.");
}
var claims = new[] { new Claim(ClaimTypes.Name, paramName) };
var credentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken("ExampleServer", "ExampleClients", claims, expires: DateTime.Now.AddSeconds(60), signingCredentials: credentials);
return JwtTokenHandler.WriteToken(token);
}
}
}
My client:
public class ClienteGrpcDotNet
{
#region constructores
public ClienteGrpcDotNet()
{
var channel = GrpcChannel.ForAddress("https://192.168.1.137:5001");
_client = channel.CreateGrpcService<IGreeterService>();
Authenticate("https://192.168.1.2:5001");
}
#endregion constructores
private IGreeterService _client;
public async Task<string?> SayHelloAsync()
{
HelloReply miRespuesta = await _client.SayHelloAsync(new HelloRequest { Name = "GreeterClient" });
return miRespuesta.Message;
}
#region autenticación
private static async Task<string> Authenticate(string paramAddress)
{
using var httpClient = new HttpClient();
using var request = new HttpRequestMessage
{
RequestUri = new Uri($"{paramAddress}/generateJwtToken?name={HttpUtility.UrlEncode(Environment.UserName)}"),
Method = HttpMethod.Get,
Version = new Version(2, 0)
};
using var tokenResponse = await httpClient.SendAsync(request);
tokenResponse.EnsureSuccessStatusCode();
var token = await tokenResponse.Content.ReadAsStringAsync();
return token;
}
#endregion autenticación
}
Thanks so much.
2 answers
Sort by: Most helpful
-
-
Bruce (SqlWork.com) 56,771 Reputation points
2022-01-10T17:26:21.087+00:00 Its pretty simple to port startup to min code. startup had two callbacks
the first is ConfigureServices. this is used to add DI services. you put this code inline after:
var builder = WebApplication.CreateBuilder(args); // add configure services code here builder.Services.Add....
the second was Configure. This configure the app after being build
var app = builder.Build(); // put configure code here app.run();
note: you don't need DI for configure because all the code in inline.