我从 .Net5 升级到 .Net6,现在我的令牌存储在双引号中,我无法验证从我的 blazor 服务器应用程序对 API 的调用

Posted

技术标签:

【中文标题】我从 .Net5 升级到 .Net6,现在我的令牌存储在双引号中,我无法验证从我的 blazor 服务器应用程序对 API 的调用【英文标题】:I upgraded to .Net6 from .Net5 and now my token is stored in double quotes and I cannot validate calls to the API from my blazor server app 【发布时间】:2021-12-27 19:48:27 【问题描述】:

我将我的 WebAPI 和 Blazor 服务器端项目从 NET5 升级到了 NET6,现在我无法验证我的 JWT 令牌。它以双引号存储在本地存储中

** 我的 JWTHandler 类用于创建令牌 **

public class JwtHandler
    
        private readonly IConfiguration _configuration;
        private readonly IConfigurationSection _jwtSettings;
        private readonly IConfigurationSection _googleSettings;
        private readonly UserManager<ApplicationUser> _userManager;
        public JwtHandler(IConfiguration configuration, UserManager<ApplicationUser> userManager)
        
            _userManager = userManager;
            _configuration = configuration;
            _jwtSettings = _configuration.GetSection("JWT");
            _googleSettings = _configuration.GetSection("Google");
        

        private SigningCredentials GetSigningCredentials()
        
            var key = Encoding.ASCII.GetBytes(_jwtSettings.GetSection("Secret").Value);
            var secret = new SymmetricSecurityKey(key);

            return new SigningCredentials(secret, SecurityAlgorithms.HmacSha256Signature);
        

        private async Task<List<Claim>> GetClaims(ApplicationUser user)
        
            var claims = new List<Claim>
            
                 new Claim(ClaimTypes.Name, user.UserName),
                 new Claim(ClaimTypes.NameIdentifier, user.Id),
                 new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            ;

            var roles = await _userManager.GetRolesAsync(user);
            foreach (var role in roles)
            
                claims.Add(new Claim(ClaimTypes.Role, role));
            

            return claims;
        

        private JwtSecurityToken GenerateTokenOptions(SigningCredentials signingCredentials, List<Claim> claims)
        
            var tokenOptions = new JwtSecurityToken(
                issuer: _jwtSettings.GetSection("ValidIssuer").Value,
                audience: _jwtSettings.GetSection("ValidAudience").Value,
                claims: claims,
                expires: DateTime.Now.AddMinutes(Convert.ToDouble(_jwtSettings.GetSection("ExpiryInMinutes").Value)),
                signingCredentials: signingCredentials);

            return tokenOptions;
        

        public async Task<string> GenerateToken(ApplicationUser user)
        
            var signingCredentials = GetSigningCredentials();
            var claims = await GetClaims(user);
            var tokenOptions = GenerateTokenOptions(signingCredentials, claims);
            var token = new JwtSecurityTokenHandler().WriteToken(tokenOptions);

            return token;
        

        public async Task<GoogleJsonWebSignature.Payload> VerifyGoogleToken(ExternalAuthDto externalAuth)
        
            try
            
                var settings = new GoogleJsonWebSignature.ValidationSettings()
                
                    Audience = new List<string>()  _googleSettings.GetSection("ClientId").Value 
                ;

                var payload = await GoogleJsonWebSignature.ValidateAsync(externalAuth.IdToken, settings);
                return payload;
            
            catch (Exception)
            
                throw;
            
        
    

** 我的代码用于存储到本地存储 **

 _interceptor.MonitorEvent();
                var response = await client.PostAsJsonAsync("Authenticate/login", loginModel);
                var result = await response.Content.ReadFromJsonAsync<AuthenticatedModel>();

                if (response.IsSuccessStatusCode)
                
                    var token = result.token;

                    await _locStorage.SetItemAsync("AuthToken", token);

                    ((AuthStateProvider)_authStateProvider).NotifyUserAuthentication(token);

                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

                    showAuthenticationError = false;
                    loginIsSuccessful = true;

                    this.NavToPage();

** 返回无效令牌异常的代码**

 var token = await _locStorage.GetItemAsStringAsync("AuthToken");

            var client = _clientFactory.CreateClient("meta");
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

                _interceptor.MonitorEvent();
                user = await client.GetFromJsonAsync<UserModel>("User/DashDetails");
                var tempDashs = (ICollection<DashboardsDTO>)await client.GetFromJsonAsync<IEnumerable<DashboardsDTO>>("User/Dashboards");
             

在我从 NET5 升级到 NET6 之前,上面的代码运行良好

【问题讨论】:

【参考方案1】:

我认为我使用的解决方案不是最好的,如果找到防止添加双引号的方法,请指教。

我的解决方案:我在返回无效令牌异常的代码中更改了 AuthenticatedHeaderValue 令牌,如下所示

发件人:client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

收件人:client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Trim('"'));

【讨论】:

以上是关于我从 .Net5 升级到 .Net6,现在我的令牌存储在双引号中,我无法验证从我的 blazor 服务器应用程序对 API 的调用的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF 上从 .NET 5 升级到 .NET 6 后开始调试失败

升级到 .NET 6 时,Web 项目引发运行时异常

升级到 .net 6 时托管的 Blazor WASM 身份验证中断

热重载不适用于升级的(.Net 5 -> .Net 6)项目

从 Azure 函数 NET 5 迁移到 NET 6 - 现在如何注册中间件

.net6 asp:在容器内运行时,默认输出日志格式为 json