2

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"] == "[email protected]" && 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?

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.