当前位置: 首页 > 知识库问答 >
问题:

JWT开启。NET Core 2.0

丌官星渊
2023-03-14

我一直在冒险让JWT在DotNet core 2.0上工作(今天即将发布最终版本)。有大量的文档,但所有的示例代码似乎都使用了不推荐的API,而且都是全新的核心代码,弄清楚应该如何实现它确实令人头晕目眩。我试过用Jose,但没用。UseJwtBearerAuthentication已被弃用,并且没有关于下一步操作的文档。

是否有人有使用dotnet core 2.0的开源项目,它可以简单地从授权标头解析JWT并允许我授权对HS256编码的JWT令牌的请求?

下面的类没有抛出任何异常,但没有授权任何请求,我也没有得到任何指示,说明它们为什么未经授权。回答是空的401,所以对我来说,这表明没有例外,但秘密不匹配。

奇怪的是,我的令牌是用HS256算法加密的,但我看不到任何指示来告诉它强制它在任何地方使用该算法。

这是我到目前为止的课程:

using System;
using System.html" target="_blank">Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json.Linq;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace Site.Authorization
{
    public static class SiteAuthorizationExtensions
    {
        public static IServiceCollection AddSiteAuthorization(this IServiceCollection services)
        {
            var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("SECRET_KEY"));

            var tokenValidationParameters = new TokenValidationParameters
            {
                // The signing key must match!
                ValidateIssuerSigningKey = true,
                ValidateAudience = false,
                ValidateIssuer = false,
                IssuerSigningKeys = new List<SecurityKey>{ signingKey },


                // Validate the token expiry
                ValidateLifetime = true,
            };

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;


            })

            .AddJwtBearer(o =>
            {
                o.IncludeErrorDetails = true;
                o.TokenValidationParameters  = tokenValidationParameters;
                o.Events = new JwtBearerEvents()
                {
                    OnAuthenticationFailed = c =>
                    {
                        c.NoResult();

                        c.Response.StatusCode = 401;
                        c.Response.ContentType = "text/plain";

                        return c.Response.WriteAsync(c.Exception.ToString());
                    }

                };
            });

            return services;
        }
    }
}

共有3个答案

田意致
2023-03-14

Asp。net Core 2.0 JWT承载令牌身份验证的Web Api演示实现

添加包“Microsoft.AspNetCore.Authentication.JwtBearer”

Startup.cs配置服务

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(cfg =>
            {
                cfg.RequireHttpsMetadata = false;
                cfg.SaveToken = true;

                cfg.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidIssuer = "me",
                    ValidAudience = "you",
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("rlyaKithdrYVl6Z80ODU350md")) //Secret
                };

            });

Startup.cs配置()

// ===== Use Authentication ======
        app.UseAuthentication();

User.cs//它是一个模型类,可以是任何东西。

public class User
{
    public Int32 Id { get; set; }
    public string Username { get; set; }
    public string Country { get; set; }
    public string Password { get; set; }
}

用户上下文。cs//它只是上下文类。它可以是任何东西。

public class UserContext : DbContext
{
    public UserContext(DbContextOptions<UserContext> options) : base(options)
    {
        this.Database.EnsureCreated();
    }

    public DbSet<User> Users { get; set; }
}

AccountController。反恐精英

[Route("[controller]")]
public class AccountController : Controller
{

    private readonly UserContext _context;

    public AccountController(UserContext context)
    {
        _context = context;
    }

    [AllowAnonymous]
    [Route("api/token")]
    [HttpPost]
    public async Task<IActionResult> Token([FromBody]User user)
    {
        if (!ModelState.IsValid) return BadRequest("Token failed to generate");
        var userIdentified = _context.Users.FirstOrDefault(u => u.Username == user.Username);
            if (userIdentified == null)
            {
                return Unauthorized();
            }
            user = userIdentified;

        //Add Claims
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.UniqueName, "data"),
            new Claim(JwtRegisteredClaimNames.Sub, "data"),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("rlyaKithdrYVl6Z80ODU350md")); //Secret
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken("me",
            "you",
            claims,
            expires: DateTime.Now.AddMinutes(30),
            signingCredentials: creds);

        return Ok(new
        {
            access_token = new JwtSecurityTokenHandler().WriteToken(token),
            expires_in = DateTime.Now.AddMinutes(30),
            token_type = "bearer"
        });
    }
}

用户控制器。反恐精英

[Authorize]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
    private readonly UserContext _context;

    public UserController(UserContext context)
    {
        _context = context;
        if(_context.Users.Count() == 0 )
        {
            _context.Users.Add(new User { Id = 0, Username = "Abdul Hameed Abdul Sattar", Country = "Indian", Password = "123456" });
            _context.SaveChanges();
        }
    }

    [HttpGet("[action]")]
    public IEnumerable<User> GetList()
    {
        return _context.Users.ToList();
    }

    [HttpGet("[action]/{id}", Name = "GetUser")]
    public IActionResult GetById(long id)
    {
        var user = _context.Users.FirstOrDefault(u => u.Id == id);
        if(user == null)
        {
            return NotFound();
        }
        return new ObjectResult(user);
    }


    [HttpPost("[action]")]
    public IActionResult Create([FromBody] User user)
    {
        if(user == null)
        {
            return BadRequest();
        }

        _context.Users.Add(user);
        _context.SaveChanges();

        return CreatedAtRoute("GetUser", new { id = user.Id }, user);

    }

    [HttpPut("[action]/{id}")]
    public IActionResult Update(long id, [FromBody] User user)
    {
        if (user == null)
        {
            return BadRequest();
        }

        var userIdentified = _context.Users.FirstOrDefault(u => u.Id == id);
        if (userIdentified == null)
        {
            return NotFound();
        }

        userIdentified.Country = user.Country;
        userIdentified.Username = user.Username;

        _context.Users.Update(userIdentified);
        _context.SaveChanges();
        return new NoContentResult();
    }


    [HttpDelete("[action]/{id}")]
    public IActionResult Delete(long id)
    {
        var user = _context.Users.FirstOrDefault(u => u.Id == id);
        if (user == null)
        {
            return NotFound();
        }

        _context.Users.Remove(user);
        _context.SaveChanges();

        return new NoContentResult();
    }
}

祝你好运!我只是个初学者。我只花了一周的时间开始学习asp。净核心。

洪光霁
2023-03-14

我的令牌验证参数(tokenValidationParameters)如下所示时起作用:

 var tokenValidationParameters = new TokenValidationParameters
  {
      ValidateIssuerSigningKey = true,
      IssuerSigningKey = GetSignInKey(),
      ValidateIssuer = true,
      ValidIssuer = GetIssuer(),
      ValidateAudience = true,
      ValidAudience = GetAudience(),
      ValidateLifetime = true,
      ClockSkew = TimeSpan.Zero
   };

    static private SymmetricSecurityKey GetSignInKey()
    {
        const string secretKey = "very_long_very_secret_secret";
        var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));

        return signingKey;
    }

    static private string GetIssuer()
    {
        return "issuer";
    }

    static private string GetAudience()
    {
        return "audience";
    }

此外,添加选项。RequireHttpsMetadata=false,如下所示:

         .AddJwtBearer(options =>
       {         
           options.TokenValidationParameters =tokenValidationParameters         
           options.RequireHttpsMetadata = false;
       });

编辑:

别忘了打电话

 app.UseAuthentication();

正在启动中。cs公司-

沈华晖
2023-03-14

这是一个带有控制器的完整工作最小样本。我希望您可以使用Postman或JavaScript调用来检查它。

>

  • appsettings.json, appset. Development.json.添加一个部分。注意,Key应该相当长,Issuer是服务的地址:

    ...
    ,"Tokens": {
        "Key": "Rather_very_long_key",
        "Issuer": "http://localhost:56268/"
    }
    ...
    

    !!! 在实际项目中,不要在appsettings中保留密钥。json文件。应将其保存在环境变量中,如下所示:

    Environment.GetEnvironmentVariable("JWT_KEY");
    

    更新:看到. net核心设置是如何工作的,您不需要完全从环境中获取它。您可以使用设置。但是,我们可能会在生产中将此变量写入环境变量,那么我们的代码将更喜欢环境变量而不是配置。

    AuthRequest。cs:Dto保存用于传递登录名和密码的值:

    public class AuthRequest
    {
        public string UserName { get; set; }
        public string Password { get; set; }
    }
    

    启动。应用程序之前的Configure()方法中的cs。UseMvc():

    app.UseAuthentication();
    

    启动。ConfigureServices()中的cs:

    services.AddAuthentication()
        .AddJwtBearer(cfg =>
        {
            cfg.RequireHttpsMetadata = false;
            cfg.SaveToken = true;
    
            cfg.TokenValidationParameters = new TokenValidationParameters()
            {
                ValidIssuer = Configuration["Tokens:Issuer"],
                ValidAudience = Configuration["Tokens:Issuer"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
            };
    
        });
    

    添加控制器:

        [Route("api/[controller]")]
        public class TokenController : Controller
        {
            private readonly IConfiguration _config;
            private readonly IUserManager _userManager;
    
            public TokenController(IConfiguration configuration, IUserManager userManager)
            {
                _config = configuration;
                _userManager = userManager;
            }
    
            [HttpPost("")]
            [AllowAnonymous]
            public IActionResult Login([FromBody] AuthRequest authUserRequest)
            {
                var user = _userManager.FindByEmail(model.UserName);
    
                if (user != null)
                {
                    var checkPwd = _signInManager.CheckPasswordSignIn(user, model.authUserRequest);
                    if (checkPwd)
                    {
                        var claims = new[]
                        {
                            new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
                            new Claim(JwtRegisteredClaimNames.Jti, user.Id.ToString()),
                        };
    
                        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));
                        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
    
                        var token = new JwtSecurityToken(_config["Tokens:Issuer"],
                        _config["Tokens:Issuer"],
                        claims,
                        expires: DateTime.Now.AddMinutes(30),
                        signingCredentials: creds);
    
                        return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
                    }
                }
    
                return BadRequest("Could not create token");
            }}
    

    就是这些人!干杯

    更新:人们询问如何获取当前用户。待办事项:

    >

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    

    在控制器中添加到构造函数:

    private readonly int _currentUser;
    public MyController(IHttpContextAccessor httpContextAccessor)
    {
       _currentUser = httpContextAccessor.CurrentUser();
    }
    

    在某处添加扩展并在控制器中使用它(使用......)

    public static class IHttpContextAccessorExtension
    {
        public static int CurrentUser(this IHttpContextAccessor httpContextAccessor)
        {
            var stringId = httpContextAccessor?.HttpContext?.User?.FindFirst(JwtRegisteredClaimNames.Jti)?.Value;
            int.TryParse(stringId ?? "0", out int userId);
    
            return userId;
        }
    }
    

  •  类似资料:
    • JWT

      增加验证逻辑 我们不想要谁都可以访问 todo 、folder 的一些API,至少我们需要用户登陆了才可以访问,这个时候我们需要 JSON Web Token。 json 代表一种格式,web 代表所处的环境,token 代表一段加密好的字符串。 它的流程通常是这样,在没登录之前访问 todo 或者 folder 是不会给你任何数据的,当我们请求 login 或者 register 接口的时候,校

    • JWT

      JWT 简介 JWT 是 Json web token 的简称, 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519).该 token 被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 tok

    • JWT

      介绍 在 imi 框架中非常方便地接入 jwt Github: https://github.com/imiphp/imi-jwt Composer 本项目可以使用composer安装,遵循psr-4自动加载规则,在你的 composer.json 中加入下面的内容: { "require": { "imiphp/imi-jwt": "~1.0" } } 然后执行

    • JWt

      JWt (Java Web Toolkit) 是一个用来开发交互式 Web 应用的 Java 工具包,参考桌面 GUI 的做法,主要面向网页 Widget 的开发。对开发人员而言,它提供了完整的 Web 规范的抽象层,基于事件机制对用户接口的数据更新进行处理。 演示地址: Hello World 报表和图表 树状列表以及拖拉控件

    • linux系统下workerman如何开机自动启动 打开/etc/rc.local,在exit 0前添加类似以下代码 ulimit -HSn 102400 /usr/bin/env php /磁盘/路径/start.php start -d exit 0

    •        确保定位功能完善情况下(可参考文档内 2.3权限设置,2.4电源管理),点击主界面右下方的轨迹图标打开轨迹记录面板。        轨迹记录面板主要包含:当前速度、平均速度、最高速度、总里程、总时间、最高海拔、最低海拔、累计爬升、累计下降、航向、图表等。        点击下方开始按钮即可开启轨迹记录