cornflourblue / aspnet-core-3-signup-verification-api

ASP.NET Core 3.1 - Boilerplate API with Email Sign Up, Verification, Authentication & Forgot Password
https://jasonwatmore.com/post/2020/07/06/aspnet-core-3-boilerplate-api-with-email-sign-up-verification-authentication-forgot-password
MIT License
226 stars 93 forks source link

Cannot revoke any authentication token #11

Open jurczewski opened 3 years ago

jurczewski commented 3 years ago

Description:

Cannot revoke token. While using "accounts/revoke-token" endpoint, every time I receive { "message": "Unauthorized" }

Steps to recreate issue:

I used following endpoints:

  1. /register - Create new user - "Registration successful, please check your email for verification instructions"
  2. /verify-email - "Verification successful, you can now login"
  3. /authenticate - Correct response with "jwtToken"

Error: /revoke-token returns: { "message": "Unauthorized" } with 401 status code

Error occurs for both roles: Admin and User.

cgrard commented 3 years ago

Yep, same here, it gives this error in the debug output:

Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Information: Authorization failed for the request at filter 'AuthorizeAttribute'.

Even though I'm properly registered and authenticated, the token is correct and everything, I really don't understand.

cgrard commented 3 years ago

OK this error is expected since I didn't sent the jwt in my POST request, now it goes through but it ends up with "Invalid token" no matter what. The problem seems to be in GetRefreshToken method, in the Account account = _context.Accounts.SingleOrDefault(u => u.RefreshTokens.Any(t => t.Token == token)); as the result is a null account.

I will keep investigating and update as soon as I find something.

Edit: In the database the token looks like "BA05C53C2648BEF5C9A8373983BFFE887DB57D956BF1696CE36A88C5C9D5B491FA8DAB21ED3D0EAC" but what the jwt that is received is like "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJuYmYiOjE1OTkwNjAzNTgsImV4cCI6MTU5OTA2MTI1OCwiaWF0IjoxNTk5MDYwMzU4fQ.OLSzpIfwNgRKzpb-YfX1-tWDQc-EIKoOAEr7IVHFzn0" so obviously it never finds the corresponding account thus it always return null.

cgrard commented 3 years ago

OK I think I figured this out, it works if you authenticate and then call revoke-token with an empty JSON like this:

curl -X POST "https://localhost:5001/accounts/revoke-token" -H "accept: */*" -H "Authorization: eyJhbGciOiJI...FTkdbw7ss1kYw" -H "Content-Type: application/json" -d "{}"

This way, it gets the refreshToken value from the cookie where the value is correct and it results with "token revoked".

However if you want to revoke a token that is not yours (i.e. not in your cookie) but for that you need to be admin and know the refreshToken value which is impossible unless you dig it directly in the database. Maybe am I missing something?