繁体   English   中英

如何从 JWT 令牌中获取不记名令牌(system.identitymodel.token.jwt.jwtsecuritytoken)

[英]how to get bearer token out of JWT token (system.identitymodel.token.jwt.jwtsecuritytoken)

我有以下代码:

 public AuthToken Authenticate(Auth auth)
        {
            using (var ctx = CiderQuestionaireContext.Create())
            {
                try
                {
                    var user = ctx.Users.SingleOrDefault(e => e.Email == auth.Email);

                    if (user == null) return null;

                    var token = generateJwtToken(user);

                    return new AuthToken
                    {
                        UserId = user.Id,
                        Token = token
                    };
                }
                catch (Exception e)
                {
                    throw e;
                }

            }
        }

它返回一个 hash,我将其发送到以下地址。 下面的字符串标记参数是我从上面的调用中得到的返回值。

 public JwtSecurityToken Validated(string token)
        {//must return bearertoken
            try
            {
                var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
                new JwtSecurityTokenHandler().ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    // set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
                    ClockSkew = TimeSpan.Zero
                }, out SecurityToken validatedToken);

                var jwtToken = (JwtSecurityToken)validatedToken;
                var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);
                var user = GetById(userId);

                if (user == null)
                    return null;
                else
                    return jwtToken;
            }
            catch(Exception e)
            {
                throw e;//new Exception(Resource.InvalidToken);
            }
        }

但我需要返回一个不记名令牌。

我究竟做错了什么? 或者也许它被退回了,我没有意识到。 另外,那么如何在整个应用程序中使用“承载令牌”来保证其他 API 的安全? 现在,我在每个 controller 的顶部调用“授权”属性......

回报是:

{
    "actor": null,
    "audiences": [],
    "claims": [
        {
            "issuer": "LOCAL AUTHORITY",
            "originalIssuer": "LOCAL AUTHORITY",
            "properties": {},
            "subject": null,
            "type": "id",
            "value": "6",
            "valueType": "http://www.w3.org/2001/XMLSchema#string"
        },
        {
            "issuer": "LOCAL AUTHORITY",
            "originalIssuer": "LOCAL AUTHORITY",
            "properties": {},
            "subject": null,
            "type": "nbf",
            "value": "1618714791",
            "valueType": "http://www.w3.org/2001/XMLSchema#integer"
        },
        {
            "issuer": "LOCAL AUTHORITY",
            "originalIssuer": "LOCAL AUTHORITY",
            "properties": {},
            "subject": null,
            "type": "exp",
            "value": "1618721991",
            "valueType": "http://www.w3.org/2001/XMLSchema#integer"
        },
        {
            "issuer": "LOCAL AUTHORITY",
            "originalIssuer": "LOCAL AUTHORITY",
            "properties": {},
            "subject": null,
            "type": "iat",
            "value": "1618714791",
            "valueType": "http://www.w3.org/2001/XMLSchema#integer"
        }
    ],
    "encodedHeader": "eyJhbaaaaaaaaaaaaaaaaaaaaaaaaa6IkpXVCJ9",
    "encodedPayload": "eyJpZCI6IjYiLCJuYaaaaaaaaaaaaaaaaMSwiaWF0IjoxNjE4NzE0NzkxfQ",
    "header": {
        "alg": "HS256",
        "typ": "JWT"
    },
    "id": null,
    "issuer": null,
    "payload": {
        "id": "6",
        "nbf": 1618714791,
        "exp": 1618721991,
        "iat": 1618714791
    },
    "innerToken": null,
    "rawAuthenticationTag": null,
    "rawCiphertext": null,
    "rawData": "eyJaaaaaaaaaaaaaaaaaaaaaadt0L5_f8BR5UCPuKXk",
    "rawEncryptedKey": null,
    "rawInitializationVector": null,
    "rawHeader": "eyaaaaaaaaaaaaaaapXVCJ9",
    "rawPayload": "eyaaaaaaaaaaaaaaaI6MTYxODcyMTk5MSwiaWF0IjoxNjE4NzE0NzkxfQ",
    "rawSignature": "aaaaaaaaaaaaaaApoYZZaG7Lk5dt0L5_f8BR5UCPuKXk",
    "securityKey": null,
    "signatureAlgorithm": "HS256",
    "signingCredentials": null,
    "encryptingCredentials": null,
    "signingKey": {
        "keySize": 512,
        "keyId": null,
        "cryptoProviderFactory": {
            "cryptoProviderCache": {},
            "customCryptoProvider": null,
            "cacheSignatureProviders": true
        }
    },
    "subject": null,
    "validFrom": "2021-04-18T02:59:51Z",
    "validTo": "2021-04-18T04:59:51Z",
    "issuedAt": "2021-04-18T02:59:51Z"
}

要使用 JWT Bearer Token 作为 ASP.NET Core 的身份验证方法,首先您需要在 Startup.cs 中配置 JWT Bearer 作为身份验证方法。

内部配置服务

services.AddAuthentication(options =>  
 {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.SaveToken = true;
            options.RequireHttpsMetadata = false;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidIssuer = Configuration.GetSection("Issuer").Value,//getting from appsettings.json
                ValidAudience = Configuration.GetSection("Audience").Value,//getting from appsettings.json
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("SecretKey").Value))
            };
});

然后在 Configure 方法里面

app.UseAuthentication(); 
app.UseAuthorization();

生成令牌

public string GetToken(IConfiguration configuration, ApplicationUser userModel)
    {
        _ = int.TryParse(configuration.GetSection("UserTokenExpireDays").Value, out var expireDays);
       
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            new Claim(ClaimTypes.Email, userModel.Email),
            new Claim(ClaimTypes.Name, userModel.UserName),
            new Claim(ClaimTypes.NameIdentifier, userModel.Id),  
            new Claim(ClaimTypes.Country, userModel.CountryCode),//if any
            new Claim(ClaimTypes.Locality, userModel.Country.ToString()),//if any
            // Add more claims you if you need.
        };

        return CreateToken(configuration, expireDays, claims);
    } 

    private static string CreateToken(IConfiguration configuration, int expireDays, Claim[] claims)
    {            
        var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration.GetSection("SecretKey").Value)); 

        var token = new JwtSecurityToken
        (
            issuer: configuration.GetSection("Issuer").Value,
            audience: configuration.GetSection("Audience").Value,
            expires: DateTime.UtcNow.AddMonths(1),
            claims: claims,
            signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
        );
        return new JwtSecurityTokenHandler().WriteToken(token);
    }  

现在您可以获得一个 JWT 承载令牌来保护您的 Controller 操作方法,您获得的令牌需要在每次调用 header 中添加它,如下所示。

const request = req.clone({ //req is an Angular HttpRequest
     setHeaders: {
              Authorization: `Bearer ${the_token}`
          } 
     });

现在,您在 ASP.NET 核心应用程序中拥有了一个完全工作的 JWT 承载身份验证。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM