对核心API的Dotnet Core 3 MVC身份验证

时间:2019-10-03 04:15:35

标签: c# .net asp.net-mvc .net-core jwt

两个单独的项目,都是DotNet Core 3:API和Web MVC。
MVC和移动应用程序都仅与API通讯。

MVC需要通过API对用户进行身份验证(并且还必须具有Google身份验证,才能传递给API),这是通过使用登录页面完成的,该页面提交到mvc上的/ account / login /向API打开一个httpclient请求,该请求返回JWT令牌。该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);”处出现错误步骤。

我做错了吗?我应该使用带有登录表单Submit的javascript直接发布到API,是否将JWT添加到标题并将MVC切换到JwtBearer身份验证?

1 个答案:

答案 0 :(得分:1)

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

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

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