简体   繁体   中英

Invalid JWT Token Auth in .NET/Angular App

I have a problem while authenticating an user. Login works perfectly and I receive a token from API. I save it in JwtTokenService in my Angular App and while performing a request (ex. Delete) I add "Authorization" header with value "Bearer token" as I did before in PostMan. Request from client:

要求

I get 302 status code and redirection to Account/Login even though I dont have such rout

重定向

Error in console:

Access to XMLHttpRequest at 'https://localhost:44332/api/car/2' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

But GETs (which have [AllowAnonymous] attribute are working fine)

Request in postman works well. I think it's something messed up with my cookies. .Net Conf:

[Route("api/[controller]")]
[ApiController]
[Authorize]
[ExceptionHandlingFilter]
public class CarController : ControllerBase
{


    [HttpDelete("{id}")]
    public async Task<IActionResult> Delete(int id)
    {
        
    }

and Startup

 services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader());
        });

 services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = configuration["Jwt:Issuer"],
                ValidAudience = configuration["Jwt:Issuer"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:Key"]))
            };

            options.Events = new JwtBearerEvents
            {
                OnMessageReceived = context =>
                {
                    var accessToken = context.Request.Query["access_token"];

                    // If the request is for our hub...
                    var path = context.HttpContext.Request.Path;
                    if (!string.IsNullOrEmpty(accessToken) &&
                        (path.StartsWithSegments("/chat")))
                    {
                        // Read the token out of the query string
                        context.Token = accessToken;
                    }
                    return Task.CompletedTask;
                }
            };
        });

app.UseCors("CorsPolicy");

EDIT1:

 [HttpDelete("{id}")]
    [Authorize(Policy = JwtBearerDefaults.AuthenticationScheme)]
    public async Task<IActionResult> Delete(int id)
    {

Error: System.InvalidOperationException: The AuthorizationPolicy named: 'Bearer' was not found.

Console error: Access to XMLHttpRequest at 'https://localhost:44332/api/car/2' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. zone-evergreen.js:2845 DELETE https://localhost:44332/api/car/2 net::ERR_FAILED

Here is an example of how I achieve this.


Add this to your start up file.

services.AddCors(options =>
{
    options.AddPolicy("MyPolicy", builder =>
    {
        builder.AllowAnyOrigin();
        builder.AllowAnyHeader();
        builder.AllowAnyMethod();
    });
});

app.UseRouting();

app.UseCors();

app.UseAuthorization();
...

Add this to your controller file.

[ApiController]
[Route("[controller]")]
// <Mainly just need to add the below attribute>
[Microsoft.AspNetCore.Cors.EnableCors("MyPolicy")]
// </Mainly just need to add the below attribute>
public class WeatherForecastController : ControllerBase
{
    [HttpPost]
    [Route("PostRequest")]
    public IActionResult PostRequest(string parameter)
    {
        return Ok(new { result = parameter });
    }
}

Client

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with 
ASP.NET Core</a>.</p>
</div>

<script
  src="https://code.jquery.com/jquery-3.5.1.js"
  integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
  crossorigin="anonymous"></script>
<script>

    $(document).ready(() =>{
        $.ajax({
            type: 'POST',
            url : 'https://localhost:44304/weatherforecast/PostRequest?parameter=someValue',
            contentType: 'application/json',
            success: function (data){
                console.log(data);
            },
            error: function (data){
                console.log(data);
            },
        });
    });
</script>

This should allow CORS.

在此处输入图片说明


If I remove [Microsoft.AspNetCore.Cors.EnableCors("MyPolicy")] from the controller, it will fail.

CorsFail



All the information you need can be found here and shouldn't be too difficult to add your project.
https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1#enable-cors-with-attributes

You have to use in ConfugureServices of Startup :

 services.AddCors(options =>
 {
   options.AddPolicy("MyPolicy", builder =>
   {
       builder.AllowAnyOrigin();
       builder.AllowAnyHeader();
       builder.AllowAnyMethod();
   });
});

And add policy name to configure in startup file:

 app.UseCors("MyPolicy");

App.UseCors() without policy name can be used only if you use .AddDefaultPolicy(...)

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