首页 > 解决方案 > Dotnet Core 3 MVC 对 Core API 的身份验证

问题描述

两个独立的项目,都是 DotNet Core 3:API 和 Web MVC。
MVC 和移动应用程序都只与 API 对话。

MVC 需要通过 API 对用户进行身份验证(并且还能够进行 google 身份验证,传递给 API),这是使用登录页面完成的,该登录页面提交到 mvc 上的 /account/login/,然后打开一个 httpclient对返回 JWT 令牌的 API 的请求。API 将使用 JWT 执行来自 Web MVC 应用程序的所有进一步操作。

不幸的是,那里的许多文档只处理 API 返回令牌,或使用 SPA 框架进行身份验证。我正在考虑使用 MVC 作为客户端。

访问返回的 JWT 声明时遇到一些问题,并确定如何将其存储在 MVC 应用程序使用的身份验证 cookie 中。

API 认证控制器/Auth/

public IActionResult Post()
        {
            //Do auth check here
            if (Request.Form["username"] == "test@test.com" && Request.Form["password"] == "test")
            {

                var authClaims = new[]
                {
                    new Claim(JwtRegisteredClaimNames.Sub, "testUsername"),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(ClaimTypes.NameIdentifier, "ID"),
                    new Claim("Name", "testName"),
                    new Claim("Email", "testEmail"),
                };

                var authSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("qwertyuiopasdfghjklzxcvbnm123456"));

                var token = new JwtSecurityToken(
                    issuer: "https://localhost",
                    audience: "https://localhost",
                    expires: DateTime.Now.AddHours(3),
                    claims: authClaims,
                    signingCredentials: new Microsoft.IdentityModel.Tokens.SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
                    );

                return Ok(new
                {
                    token = new JwtSecurityTokenHandler().WriteToken(token),
                    expiration = token.ValidTo
                });
            }
            return Unauthorized();
        }

MVC 上的 /account/login 发布操作

            var httpClient = _httpClientFactory.CreateClient("API");

            var formContent = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("username", username),
                new KeyValuePair<string, string>("password", password)
            });
            var response = await httpClient.PostAsync("https://localhost:{port}/auth", formContent);


            if (response.IsSuccessStatusCode)
            {
                

                var tokenResponse = await response.Content.ReadAsStringAsync();
                var json = JsonDocument.Parse(tokenResponse);

                var token = json.RootElement.GetProperty("token").GetRawText(); 
                var expires = json.RootElement.GetProperty("expiration").GetRawText(); 
                
                var jwt = new JwtSecurityToken(token);
                //Access claims from jwt here, set the identity claims

                //Set cookie authentication for MVC
                var iden = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                var principal = new ClaimsPrincipal(iden);
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
                //Redirect to account page
             }

令牌从 API 正确返回,但给出了一个

有三个段,但不是正确的 JWS 格式。

步骤错误var jwt = new JwtSecurityToken(token);

我以错误的方式这样做吗?我是否应该使用带有登录表单提交的 javascript 直接发布到 API,是否将 JWT 添加到标头并将 MVC 切换到 JwtBearer 身份验证?

标签: c#.netasp.net-mvc.net-corejwt

解决方案


我遇到了同样的问题,我设法使用以下代码读取了令牌:

jwt = jwt.Replace("Bearer ", string.Empty);
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = tokenHandler.ReadJwtToken(jwt);

然后,您可以使用该jwtToken.Claims集合查看声明。


推荐阅读