【问题标题】:Custom middleware with JWT authorization - IsAuthenticated=False具有 JWT 授权的自定义中间件 - IsAuthenticated=False
【发布时间】:2020-01-28 22:32:21
【问题描述】:

我编写了一个小的中间件代码(asp.net core v2.2 + c#),它在执行对服务器的调用之后运行,如果用户通过身份验证,则运行一些逻辑。由于它是 WebAPI - 身份验证是通过使用 Bearer 令牌完成的。

中间件是这样的:

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>();
    }
}

问题在于表达式httpContext.User.Identity.IsAuthenticated 总是返回false,即使请求成功通过服务验证。

我的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 =>
    {
        // ...
    });
}

我还检查了httpContext.Request 对象是否包含Authorization 标头,并且确实如此。

为什么httpContext.User 对象似乎请求未经授权?

【问题讨论】:

  • 试试services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(...)
  • 您好,感谢您的回答。结果相同。
  • 如果我没记错的话,IsAuthenticated 属性会检查是否存在“名称”声明(您也可以更改 JWT 设置中的名称声明。它不是基于身份验证是否成功.
  • 啊不,不是名称声明,而是身份验证类型:github.com/microsoft/referencesource/blob/master/mscorlib/…
  • 你的中间件是在 MVC 之后注册的,所以只有在请求不匹配任何操作时才会运行,这是故意的吗?

标签: c# asp.net asp.net-core asp.net-web-api


【解决方案1】:

这是一个简单的演示,如下所示:

1.生成令牌:

[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(和你的一样)

4.授权api:

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

5.结果:

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 2017-11-16
    • 2020-05-04
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 2017-04-15
    • 2019-06-26
    • 1970-01-01
    相关资源
    最近更新 更多