简体   繁体   中英

Dotnet Core 3 MVC authentication to Core API

Two separate projects, both DotNet Core 3: API and Web MVC.
The MVC and Mobile app both talk only to the API.

The MVC needs to authenticate the user to the API (and also be able to have google authentication, passing to the API), this is done using a login page that submits to /account/login/ on the mvc, which then opens a httpclient request to the API which returns a JWT token. The API will use the JWT for all further actions from the web MVC app.

Unfortunately a lot of the documentation out there only deals with API returning tokens, or using a SPA framework to the authentication. I'm looking at using the MVC as a client.

Having some issues accessed the returned JWT's claims, and working out how to store it in the authentication cookie that the MVC app uses.

API Auth Controller /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();
        }

The /account/login Post Action on the MVC

            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
             }

The token is returned correctly from the API, but is giving a

has three segments but is not in proper JWS format.

error at the var jwt = new JwtSecurityToken(token); step.

Am I doing this in the wrong way? Should I be using javascript with the login form submit to post to the API directly, have the JWT added to the headers and switch the MVC to JwtBearer Authentication?

I had the same problem, I managed to read the token using the following code:

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

you can then view the claims using the jwtToken.Claims collection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM