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

时间:2021-04-18 03:37:37

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

我有以下代码:

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

            }
        }

返回我发送到以下内容的哈希值。下面的字符串令牌参数是我从上面的调用中得到的回报。

 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 的安全? 现在,我在每个控制器的顶部调用“授权”属性....

返回是:

{
    "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"
}

1 个答案:

答案 0 :(得分:1)

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

ConfigureService 内部

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 承载令牌来保护您的控制器操作方法,您需要将获得的令牌添加到每个调用标头中,如下所示。

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

现在您的 ASP.NET Core 应用程序中有一个完全有效的 JWT 承载身份验证。