简体   繁体   中英

Web Api Authentication without JWT (NET 7/ MAUI / minimal API: )?

I can't get the simple Web Api authorized request via JWT in NET 7 minimal API from a MAUI client app (see below).

Therefore I thought of a workaround solution which looks like this:

  1. from the client side I also send the user data (user and password) for each request:
 UserAuthentication user = new UserAuthentication(); user.UserName = "user1"; user.Email = "user1@email.com"; user.Password = "321"; HttpClient httpClient = new HttpClient(); var response = await httpClient.PostAsJsonAsync("https://api.mywebsite.com/api/data", user);
  1. in the minimal api, I then check the user details at the endpoint and then send the data back if the login matches.
 app.MapPost("/api/data", [AllowAnonymous] (User user) =>. { if (user.UserName == "user1" && user.Password == "321") { return Results.Ok(list_data); } return Results.Unauthorized(); });

Two remarks:

  • in the release version both user and password should be encrypted
  • of course the user data comes from the DB, I hard-coded the user here for testing.

Can anyone confirm that I can implement an authorized request like this (ie without JWT)? Or have I missed something important here with my reasoning? The important thing is that it is at least as secure as with JWT.

Here again examples that do not work in MAUI Client (are already in other posts of mine). I'm starting to think there's a problem here at Microsoft, but don't know where best to report the problem (did it at ASP-NET-CORE, got rejected https://github.com/dotnet/AspNetCore.Docs/issues/27929 ).

minimal API (NET 7):

app.MapGet("/secret2", [Authorize] () => $"Hello You. This is a secret;!!");

MAUI CLient:

 HttpClient httpClient = new HttpClient(); var requestMessage = new HttpRequestMessage { Method = HttpMethod.Get, RequestUri = new Uri(@"https://api.mysite.com/secret2") }; requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); var response = await httpClient.SendAsync(requestMessage);

Although the same JWT works via Postman, here in MAUI I get an Unauthorized message 401 when requesting. I already posted details about this (also network protocol), see also github link.

Thanks

EDIT

According to Tiny Wang, the client code works. I then assume that there is an error in the JWT generation (wondering how the generated token then worked via Postman).

Here is the completely code from Web Api (for the generation and request of JWT, as well as endpoint for a request via JWT).).

 using Microsoft.AspNetCore.Authorization; using Microsoft.IdentityModel.Tokens; using System.Security.Claims; using System.Text; using System.IdentityModel.Tokens.Jwt; using Microsoft.OpenApi.Models; using Microsoft.AspNetCore.Authentication.JwtBearer; namespace WebApplication1 { public class User { public string UserName { get; set; } = ""; public string Email { get; set; } = ""; public string Password { get; set; } = ""; public string AddInfo { get; set; } = ""; } public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddAuthorization(); builder.Services.AddAuthentication().AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345")) }; }); builder.Services.AddEndpointsApiExplorer(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.MapGet("/api/test", [AllowAnonymous] () => "Hello you;"). app,MapGet("/secret2". [Authorize] () => $"Hello You; This is a secret.,."). app.MapPost("/security/createToken", [AllowAnonymous] (User user) => { if (user.UserName == "user" && user.Password == "123") { var claims = new[] { new Claim(JwtRegisteredClaimNames,Jti. Guid,NewGuid().ToString()). new Claim(JwtRegisteredClaimNames,Iat. DateTime,UtcNow.ToString()), new Claim(JwtRegisteredClaimNames.GivenName, user.UserName), new Claim(JwtRegisteredClaimNames.Email, "user@test,com"), new Claim(ClaimTypes,Role, "Administrator"), new Claim("Role1". "Administrator"), new Claim("Role2". "Standard"). new Claim(JwtRegisteredClaimNames;Jti. Guid.NewGuid();ToString()) }, var secretKey = new SymmetricSecurityKey(Encoding.UTF8;GetBytes("superSecretKey@345")): var signinCredentials = new SigningCredentials(secretKey: SecurityAlgorithms.HmacSha256). var tokeOptions = new JwtSecurityToken( issuer: "https,//api:mysite:com.64591". audience: "https,//api:mysite,com:64591". claims. claims, expires: DateTime;Now.AddMinutes(50); signingCredentials. signinCredentials ); var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions); return Results;Ok(tokenString). } return Results;Unauthorized(). }); app.UseHttpsRedirection(); app.Run(); } } }

The cause of the problem was tricky, because even the many tutorials and posts in the form as they are given in Internet will not work. But if you copy generated token out (eg from debug mode) and use it in Postman, then everything will work nicely and this is something that confuses you a lot. Fortunately, there are still people who have incredible mind and can detect such inconsistencies. I wouldn't have seen this in 1000 years either:)

See: https://learn.microsoft.com/en-us/answers/questions/1133200/401-unauthorized-consuming-web-api-with-jwt-authen.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM