C# Dotnet 6 web api : Authentification Token Bear JWT

jurjerie Messages postés 28 Date d'inscription mercredi 24 avril 2019 Statut Membre Dernière intervention 19 août 2023 - 19 août 2023 à 16:47
scriptiz Messages postés 1424 Date d'inscription dimanche 21 décembre 2008 Statut Membre Dernière intervention 14 septembre 2023 - 14 sept. 2023 à 00:25

Bonjour à tous, 

Je suis en train de développer une petite application, et je suis bloqué sur la partie de l'authentification. Le token est bien généré et il contient bien les bonnes données sur debugger du site JWT, mais il met impossible de passer l'authentification sur le controller ou j'ai mis la sécurité :

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

J'ai l'impression que le token n'est pas enregistrer dans la base de données et donc la vérification par celui-ci n'est pas possible.

Malgré avoir regardé diverses vidéos sur comment le mettre en place et impossible de trouver l'élément qu'il me manque pour résoudre ce problème. 

Avez-vous une solution à me proposer ?

Merci d'avance pour votre aide, 

Bonne journée,
 

Le Programe.cs

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Zcode.Core.Zcode.Infrastructures.Data;
using Zcode.ExtensionMethods;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCustomSecurity(builder.Configuration);
//builder.Services.AddDbContext<SelfiesContext>();
//builder.Configuration.GetConnectionString("SelfieDataBase");

builder.Services.AddInjection();
var connectionString = builder.Configuration.GetConnectionString("ZcodeDB");

builder.Services.AddDbContext<ZcodeContext>(options => options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));

builder.Services.AddDefaultIdentity<IdentityUser>(options =>
{
    //options.Password.RequiredLength = 8;
    options.SignIn.RequireConfirmedEmail = false;
}).AddEntityFrameworkStores<ZcodeContext>();

var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseCors(SecurityMethods.DEFAULT_POLICY);
app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

SecurityMethods.cs

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

namespace Zcode.ExtensionMethods;

public static class SecurityMethods
{
    // about security (cords, jwt, etc.)

    #region Constants

    public const string DEFAULT_POLICY = "DEFAULT_POLICY";

    #endregion
    #region Public  Methods

    public static void AddCustomSecurity(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddCustomCors(configuration);
        services.AddCustomAuthentication(configuration);
    }

    public static void AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddAuthentication(option =>
        {
            option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;  
            option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

        }).AddJwtBearer(options =>
        {
            options.SaveToken = true;
            options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
            {
                IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(configuration["Jwt:Key"]!)),
                ValidateAudience = false,
                ValidateIssuer = false,
                ValidateActor = false,
                ValidateLifetime = true,
            };

        });
    }

        public static void AddCustomCors(this IServiceCollection services, IConfiguration configuration)
    {
        // Get the CORS origins configuration
        string[] corsOrigins = configuration.GetSection("Cors:Origins").Get<string[]>()!;

        // Check if the corsOrigins is null or empty before setting the CORS policy
        if (corsOrigins != null && corsOrigins.Length > 0)
        {
            services.AddCors(options =>
            {
                options.AddPolicy(DEFAULT_POLICY, builder =>
                {
                    builder.WithOrigins(corsOrigins)
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
            });
        }
        else
        {
            // If corsOrigins is null or empty, you may choose to handle the situation accordingly.
            // For example, you could throw an exception, use a default value, or simply not set the CORS policy.
            // Here, I'll just log a warning.
            Console.WriteLine("Warning: CORS origins configuration is null or empty. No CORS policy will be set.");
        }
    }


    #endregion
}

AuthentificationController.cs :

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using Zcode.Application.DTOs;

namespace Zcode.Controllers
{
    [Route("api/v1/[controller]")]
    [ApiController]
    public class AuthenticateController : ControllerBase
    {

        #region Fields
        private UserManager<IdentityUser> userManager;
        private IConfiguration configuration;
        #endregion

        #region Constructors

        public AuthenticateController(UserManager<IdentityUser> userManager, IConfiguration configuration)
        {
            this.userManager = userManager;
            this.configuration = configuration;
        }

        #endregion

        #region Public methods
        [HttpPost]
        public async Task<IActionResult> Login([FromBody] AuthenticateUserDTO userDTO)
        {
            IActionResult result = this.BadRequest();

            var user = await this.userManager.FindByEmailAsync(userDTO.Email);

            if (user != null)
            {
                bool passwordIsGood = await this.userManager.CheckPasswordAsync(user, userDTO.Password);
                if (passwordIsGood)
                {
                    this.Ok(new AuthenticateUserDTO()
                    {
                        Email = user.Email,
                        Token = this.GenerateJwtToken(user),
                        
                    });
                }
            }

            return result;

        }

        [HttpPost]
        [Route("register")]
        public async Task<IActionResult> Register([FromBody] AuthenticateUserDTO userDTO)
        {
            IActionResult result = this.BadRequest();

            var user = new IdentityUser(userDTO.Email);

            user.Email = userDTO.Email;
            user.UserName = userDTO.Username;


            var succes = await userManager.CreateAsync(user);
            if (succes.Succeeded)
            {
                var token = this.GenerateJwtToken(user);
                userDTO.Token = token;
                result = this.Ok(userDTO);
            }


            return result;
        }

        #endregion

        #region Internal methods

        private string GenerateJwtToken(IdentityUser user)
        {
            var jwtTokenHandler = new JwtSecurityTokenHandler();

            var key = Encoding.UTF8.GetBytes(configuration["Jwt:Key"]);

            using (var hmac = new HMACSHA256())
            {
                key = hmac.Key;
            }

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim("Id", user.Id),
                    new Claim(JwtRegisteredClaimNames.Sub, user.Email),
                    new Claim(JwtRegisteredClaimNames.Email, user.Email),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
                }),
                Expires = DateTime.UtcNow.AddHours(6),
                SigningCredentials = new SigningCredentials (new SymmetricSecurityKey(key),
                SecurityAlgorithms.HmacSha512Signature),
            };

            var token = jwtTokenHandler.CreateToken(tokenDescriptor);

            var jwtToken = jwtTokenHandler.WriteToken(token);

            return jwtToken;
        }
    }
        #endregion
}

 ps : j'utilise le package : Microsoft.AspNetCore.Authentication.JwtBearer


A voir également:

1 réponse

scriptiz Messages postés 1424 Date d'inscription dimanche 21 décembre 2008 Statut Membre Dernière intervention 14 septembre 2023 425
14 sept. 2023 à 00:25
0