簡體   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