Custom middleware with JWT authorization - IsAuthenticated=False

故事扮演 提交于 2020-04-18 07:05:12

问题


I wrote a small middleware code (asp.net core v2.2 + c#) that run AFTER a call to server is executed and run some logic if the user is authenticated. Since it's WebAPI - the authentication is done by using Bearer token.

This how the middleware looks like:

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        await _next(httpContext).ConfigureAwait(false); // calling next middleware

        if (httpContext.User.Identity.IsAuthenticated) // <==================== Allways false
        {
            // Do my logics
        }
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class MyMiddlewareExtensions
{
    public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyMiddleware>();
    }
}

The problem is that the expression httpContext.User.Identity.IsAuthenticated allways return false, even if the request successfully authenticated with the service.

My Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ... 
    app.UseAuthentication();

    app.UseRequestLocalization(new RequestLocalizationOptions
    {
        DefaultRequestCulture = new RequestCulture("en-US"),
        // Formatting numbers, dates, etc.
        SupportedCultures = new[] { new CultureInfo("en-US") },
        // UI strings that we have localized.
        SupportedUICultures = supportedCultures,

    });

    app.UseMvc();
    app.UseMyMiddleware(ConfigurationManager.ApplicationName);
}

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddAuthentication().AddJwtBearer(options =>
    {
        // ...
    });
}

I also checked that the httpContext.Request object contain the Authorization header and it does.

Why the httpContext.User object seems like the request is unauthorized?


回答1:


Here is a simple demo like below:

1.Generate the token:

[Route("api/[controller]")]
[ApiController]
public class LoginController : Controller
{
    private IConfiguration _config;

    public LoginController(IConfiguration config)
    {
        _config = config;
    }
    [AllowAnonymous]
    [HttpPost]
    public IActionResult Login([FromBody]UserModel login)
    {
        IActionResult response = Unauthorized();
        var user = AuthenticateUser(login);

        if (user != null)
        {
           var tokenString = GenerateJSONWebToken(user);
            response = Ok(new { token = tokenString });
        }

        return response;
    }

    private string GenerateJSONWebToken(UserModel userInfo)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
        var claims = new List<Claim>{
            new Claim(JwtRegisteredClaimNames.Sub, userInfo.Username),
            new Claim(JwtRegisteredClaimNames.Email, userInfo.EmailAddress),
            new Claim("DateOfJoing", userInfo.DateOfJoing.ToString("yyyy-MM-dd")),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };
        var token = new JwtSecurityToken(_config["Jwt:Issuer"],
          _config["Jwt:Issuer"],
          claims: claims,
          expires: DateTime.Now.AddMinutes(30),
          signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(token);
    }
    private UserModel AuthenticateUser(UserModel login)
    {
        UserModel user = null;
        //Validate the User Credentials  
        //Demo Purpose, I have Passed HardCoded User Information  
        if (login.Username == "Jignesh")
        {
            user = new UserModel { Username = "Jignesh Trivedi", EmailAddress = "test.btest@gmail.com" };
        }
        return user;
    }
}

2.Startup.cs:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(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"]))
                };
            });
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //...
        app.UseMyMiddleware();

        app.UseAuthentication();
        app.UseHttpsRedirection();
        app.UseMvc();
    }

3.custom MyMiddleware(the same as yours)

4.Authorize api:

[HttpGet]
[Authorize]
public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "High Time1", "High Time2", "High Time3", "High Time4", "High Time5" };                    
    }

5.Result:



来源:https://stackoverflow.com/questions/58154183/custom-middleware-with-jwt-authorization-isauthenticated-false

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!