简体   繁体   English

在 .NET 7 MAUI 中使用 JWT 认证消费 web api?

[英]Consuming web api with JWT authentication in .NET 7 MAUI?

I have a minimal API .NET 7 installed on an external web server and use JWT for authentication.我在外部 web 服务器上安装了最小的 API .NET 7 并使用 JWT 进行身份验证。 For testing I created a few endpoints (with authentication and also without) so I can test the web API via Postman. I start Postman from my private machine and access the web address of the API to test everything.为了进行测试,我创建了一些端点(有和没有身份验证),因此我可以通过 Postman 测试 web API。我从我的私人机器启动 Postman 并访问 API 的 web 地址以测试所有内容。

Now everything works as expected.现在一切都按预期工作。 I can log in via Postman, then I get JWT and if I enter JWT in Postman, then I can also access protected endpoint and get the data from the Web API.我可以通过 Postman 登录,然后我得到 JWT,如果我在 Postman 中输入 JWT,那么我也可以访问受保护的端点并从 Web API 中获取数据。

Now I have created a desktop application in MAUI .NET 7 and I want to use this web API. Also here the access to unprotected endpoint works as well as logging in with receiving the JWT. Only the last part of the whole thing does not work anymore and that is access to a protected endpoint with the delivery of JWT for which I constantly get the message 401 Unauthorized.现在我已经在 MAUI .NET 7 中创建了一个桌面应用程序,我想使用这个 web API。同样在这里,对未受保护的端点的访问以及接收 JWT 的登录都有效。只有整个事情的最后一部分不再起作用那就是通过交付 JWT 访问受保护的端点,为此我不断收到消息 401 Unauthorized。 If I then put the same JWT into Postman, then the request goes through Posstman and I get the data from Web API!如果我然后将相同的 JWT 放入 Postman,那么请求将通过 Posstman,我从 Web API 获取数据!

I have been looking for a solution and have tried all possible code examples from the inte.net.我一直在寻找解决方案并尝试了来自 inte.net 的所有可能的代码示例。 For example:例如:

 var requestMessage = new HttpRequestMessage { Method = HttpMethod.Get, RequestUri = new Uri("http://api.mywebsite.com:64591/secret") }; requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Token.token); var response = await _httpClient.SendAsync(requestMessage);

or或者

 _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", Token.token); var RawData = await _httpClient.GetStringAsync("http://api.mywebsite.com:64591/secret2");

In some places I read that there were problems with the change to .NET 6. The solution was new NuGet packages, but since I'm already on .NET 7, I installed the latest versions.在某些地方,我读到更改为 .NET 6 存在问题。解决方案是新的 NuGet 包,但由于我已经在 .NET 7 上,所以我安装了最新版本。

There was also a post suggesting that in the web API you set issuer and audience to false.还有一个帖子建议在 web API 中将 issuer 和 audience 设置为 false。 I did that as well, but to no success.我也这样做了,但没有成功。

 ValidateIssuer = false, ValidateAudience = false,

Does anyone have a working code for MAUI native app that consumes minimal API?有没有人有消耗最少 API 的 MAUI 本机应用程序的工作代码?

EDIT编辑

Following Heretic Monkey's suggestion, I installed Wireshark software and analyzed Network Transfer.按照Heretic Monkey的建议,我安装了Wireshark软件,分析了Network Transfer。

Here is what I found:这是我发现的:

  • the token I receive from Web Api after authentication, I also send in the same form when requesting to an Authorized Endpoint (so received and sent token from client are identical).身份验证后我从 Web Api 收到的令牌,我在向授权端点请求时也以相同的形式发送(因此从客户端接收和发送的令牌是相同的)。 My conclusion here is that the token is correct.我在这里的结论是令牌是正确的。
  • When the request with the JWT is sent from the client to the server (Web Api), I then get the error message 401. In the log I see below information with the reason Bearer error="invalid_token":当带有 JWT 的请求从客户端发送到服务器(Web Api)时,我收到错误消息 401。在日志中,我看到以下信息,原因是 Bearer error="invalid_token":
 Hypertext Transfer Protocol HTTP/1.1 401 Unauthorized\r\n [Expert Info (Chat/Sequence): HTTP/1.1 401 Unauthorized\r\n] [HTTP/1.1 401 Unauthorized\r\n] [Severity level: Chat] [Group: Sequence] Response Version: HTTP/1.1 Status Code: 401 [Status Code Description: Unauthorized] Response Phrase: Unauthorized Transfer Encoding: chunked\r\n Server: Microsoft-IIS/10.0\r\n WWW-Authenticate: Bearer error="invalid_token"\r\n X-Powered-By: ASP.NET\r\n Date: Sun, 18 Dec 2022 09:07:00 GMT\r\n \r\n [HTTP response 1/1] [Time since request: 0.047969000 seconds] [Request in frame: 790] [Request URI: http://api.myserver.com:64591/secret2] HTTP chunked response End of chunked encoding Chunk size: 0 octets \r\n File Data: 0 bytes

There are only two error reasons I could think of:我能想到的错误原因只有两个:

  1. I still have a bug in my minimal API (Web Api) and that is regarding the JWT I get from the client and somehow still need to convert/crimp the JWT maybe?, By the fact that I may use JWT in exactly the form that is sent to client.我的最小 API(Web Api)中仍然有一个错误,这是关于我从客户端获得的 JWT 并且不知何故仍然需要转换/压接 JWT 吗?事实上,我可以使用 JWT 的形式发送给客户端。 then it may be that it is wrong and that is why this error message "invalid_token" comes.那么它可能是错误的,这就是出现此错误消息“invalid_token”的原因。
  2. the second cause could be.NET 7, so an error that occurs not because my code is wrong but because it is implemented incorrectly in.NET 7 (is of course not probable but not impossible).第二个原因可能是.NET 7,所以发生错误不是因为我的代码有误,而是因为它在.NET 7 中实现不正确(当然不太可能,但并非不可能)。

Maybe someone has a suggestion how I can fix this error?也许有人建议我如何解决这个错误?

If this doesn't work (ie a request to Web Api with JWT authentication), then Web Api is unusable in.NET 7 and I really can't imagine that.如果这不起作用(即通过 JWT 身份验证向 Web Api 发出的请求),那么 Web Api 在 .NET 7 中将无法使用,我真的无法想象。

So I truly assume that the bug is in my implementation (either server/minimal Api or client MAUI.NET 7).所以我真的假设错误是在我的实现中(服务器/最小 Api 或客户端 MAUI.NET 7)。

Thanks谢谢

The problem was already kind of strange, because even the many tutorials and posts in the form as they are given in Internet will not work.这个问题已经有点奇怪了,因为即使是 Internet 上提供的许多教程和帖子也无法正常工作。 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.但是如果你复制生成的令牌(例如从调试模式)并在 Postman 中使用它,那么一切都会很好地工作,这让你很困惑。 Fortunately, there are still people who have incredible mind and can detect such inconsistencies.幸运的是,仍有人拥有不可思议的头脑,能够发现这种不一致之处。 I wouldn't have seen this in 1000 years either:)我也不会在 1000 年内看到这个 :)

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

In My case I noticed that response.Content.ReadAsStringAsync().Result in .NET MAUI will return "+token+", i have trimmed the quotation mark ("), and it worked with me在我的例子中,我注意到 .NET MAUI 中的 response.Content.ReadAsStringAsync().Result 将返回“+token+”,我已经修剪了引号 ("),它与我一起工作

using HttpResponseMessage response = await client.PostAsJsonAsync("Login", loginData);使用 HttpResponseMessage response = await client.PostAsJsonAsync("Login", loginData);

    response.EnsureSuccessStatusCode();

    string token =   response.Content.ReadAsStringAsync().Result;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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