locked
.Net Web API Login whats the best standard. JWT? RRS feed

  • Question

  • User-544325736 posted

    Hello all,

    I have a web api and a MVC front end that is working (CRUD).

     Now I want the use to be able to login and be validated. I been setting up and learning JWT assuming this is still the best standard to be using with .Net Core.

    I have created a token and it validates with postman.

    Would I need to create a validatetoken method or when I login and on my server that is all the validation it needs.

    I’m not positive how to use this yet with my api returning the token and having the use validated.

     

    What suggestions do you all have,

    Here is what I created.

    private string GenerateToken(string user)
            {
                var secretKey = configuration.GetValue<string>("Tokens:Key");
                var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
                var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
                var claims = new Claim[]
                {
                   // new Claim(JwtRegisteredClaimNames.Sub, user.Id),
                    new Claim(JwtRegisteredClaimNames.UniqueName, user)//user.UserName),
                   // new Claim(JwtRegisteredClaimNames.Email, user.Email)
    
                };
                var jsonToken = new JwtSecurityToken(
                                    signingCredentials: signingCredentials,
                                    claims: claims,
                                    expires: DateTime.UtcNow.AddMinutes(5),
                                    audience: this.configuration.GetValue<String>("Tokens:Audience"),
                                    issuer: this.configuration.GetValue<String>("Tokens:Issuer")
                                  );
    
                return new JwtSecurityTokenHandler().WriteToken(jsonToken);
                //return new JwtSecurityTokenHandler().CreateJwtSecurityToken(jsonToken);
    
            }
    
            [AllowAnonymous]
            [HttpPost("Authenticate")]
            public async Task<IActionResult> Authenticate(string username, string password)
            {
                if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password))
                {
                    var result = await signInManager.PasswordSignInAsync(username, password, false, false);
                    if (result.Succeeded)
                    {
                        return Ok(GenerateToken(username));
                    }
                    //return BadRequest(ModelState.AddModelError("Login Fail", "invalid credentials"));
                    return BadRequest("Login Fail");
                }
                return BadRequest();
            }

    Wednesday, December 30, 2020 8:42 PM

Answers

  • User475983607 posted

    ExceedingLife

    Is there such a thing where I can insert a bearer token before calling Return View() or return RedirectToAction().

    No.   A View does not have a bearer token.  Similarly, a redirect is an HTTP response returned to the browser.  The browser is not looking for a bearer token in a redirect and does forward the token.

    Below is an example of how this could work in an MVC application.  Again, the key is using cookie authentication.  

    Model passed between Web API and MVC.

        public class LoginResponse
        {
            public string token { get; set; }
            public List<ClaimDto> claims { get; set; }
            public string role { get; set; }
        }
    
        public class ClaimDto
        {
            public string type { get; set; }
            public string value { get; set; }
        }

    Web API.  The AuthenticateMvc method just populates the LoginResponse.

    //POST: /Account/AuthenticateMvc
    [AllowAnonymous]
    [HttpPost("authenticatemvc")]
    public IActionResult AuthenticateMvc([FromBody] LoginModel model)
    {
        LoginResponse result = _authService.AuthenticateMvc(model.Username, model.Password);
    
        if (result == null || string.IsNullOrEmpty(result.token))
        {
            return BadRequest(new { message = "Username or password is incorrect" });
        }
        return Ok(result);
    }

    On the client MVC application I created a basic service that calls the Web API authentication endpoint and deserialize the response.

        public interface ICustomAuthenticateService
        {
            Task<LoginResponse> Authenticate(LoginRequest login);
        }
    
        public class CustomAuthenticateService : ICustomAuthenticateService
        {
            private readonly IHttpClientFactory _clientFactory;
            public CustomAuthenticateService(IHttpClientFactory clientFactory)
            {
                _clientFactory = clientFactory;
            }
    
            public async Task<LoginResponse> Authenticate(LoginRequest login)
            {
                var json = new StringContent(
                    JsonSerializer.Serialize(login),
                    Encoding.UTF8,
                    "application/json");
    
                HttpClient client = _clientFactory.CreateClient("CustomAuthentication");
                using HttpResponseMessage response = await client.PostAsync("Account/AuthenticateMvc", json);
                {
                    string res = await response.Content.ReadAsStringAsync();
                    response.EnsureSuccessStatusCode();
                    using (var responseStream = await response.Content.ReadAsStreamAsync())
                    {
                        return await JsonSerializer.DeserializeAsync<LoginResponse>(responseStream);
                    }
                }
    
            }
        }

    Authentication cookie and service registration.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options => {
                options.LoginPath = "/Account/Index";
                options.ExpireTimeSpan = TimeSpan.FromSeconds(10);
                options.SlidingExpiration = true;
                });
    
        services.AddHttpClient("CustomAuthentication", c =>
        {
            c.BaseAddress = new Uri("https://localhost:44355/");
            c.DefaultRequestHeaders.Add("Accept", "application/json");
        });
    
        services.AddScoped<ICustomAuthenticateService, CustomAuthenticateService>();
    }

    MVC Implementation.

    public class AccountController : Controller
        {
            private readonly ICustomAuthenticateService _authService;
            public AccountController(ICustomAuthenticateService authSerivce)
            {
                _authService = authSerivce;
            }
    
            public IActionResult Index()
            {
                return View();
            }
    
            [HttpPost]
            public async Task<IActionResult> Login(LoginRequest login)
            {
                //Authenticate with web API
                LoginResponse results = await _authService.Authenticate(login);
    
                List<Claim> claims = new List<Claim>();
                foreach(var c in results.claims)
                {
                    claims.Add(new Claim(c.type, c.value));
                }
                //Added the token to the cliams collection.  
                //I'm not sure where you want to persist the token
                claims.Add(new Claim("token", results.token));
                //Also adding the role, "User", to the claims.  
                //I'm not sure if you are using roles
                claims.Add(new Claim(ClaimTypes.Role, results.role));
    
                var claimsIdentity = new ClaimsIdentity(
                    claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
                var authProperties = new AuthenticationProperties
                {
                    //AllowRefresh = <bool>,
                    // Refreshing the authentication session should be allowed.
    
                    ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
                    // The time at which the authentication ticket expires. A 
                    // value set here overrides the ExpireTimeSpan option of 
                    // CookieAuthenticationOptions set with AddCookie.
    
                    IsPersistent = false,
                    // Whether the authentication session is persisted across 
                    // multiple requests. When used with cookies, controls
                    // whether the cookie's lifetime is absolute (matching the
                    // lifetime of the authentication ticket) or session-based.
    
                    //IssuedUtc = <DateTimeOffset>,
                    // The time at which the authentication ticket was issued.
    
                    //RedirectUri = <string>
                    // The full path or absolute URI to be used as an http 
                    // redirect response value.
                };
    
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    new ClaimsPrincipal(claimsIdentity),
                    authProperties);
    
                return RedirectToAction("Index", "Home");
            }
        }

    Login View

    <form asp-action="Login">
        <div>
            <input name="Username" type="text" value="username" />
        </div>
        <div>
            <input name="Password" type="text" value="password" />
        </div>
        <div>
            <input id="Submit1" type="submit" value="submit" />
        </div>
    </form>

    Home/Index View that displays the claims.

    <h2>Claims</h2>
    
    <dl>
        @foreach (var claim in User.Claims)
        {
            <dt>@claim.Type</dt>
            <dd>@claim.Value</dd>
        }
    </dl>

    Results

    Claims
    http://schemas.microsoft.com/ws/2008/06/identity/claims/role
    UserRole
    http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
    email@email.com
    token
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IjEiLCJuYmYiOjE2MDk2ODcxOTEsImV4cCI6MTYxMDI5MTk5MSwiaWF0IjoxNjA5Njg3MTkxLCJpc3MiOiJJc3N1ZXIiLCJhdWQiOiJBdWRpZW5jZSJ9.M18S5qwDHFmYdrlPmBJD0-RJ5O_4Z963_S3T63YpH04
    http://schemas.microsoft.com/ws/2008/06/identity/claims/role
    User

    Make an effort to read the linked documentation and learn the basics.  

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, January 3, 2021 3:40 PM

All replies

  • User475983607 posted

    The JWT token middleware validates a token according to the configuration you write.  You did not share any relevant code or explain the general security design which makes answer your question very very difficult. 

    https://docs.microsoft.com/en-us/dotnet/architecture/microservices/secure-net-microservices-web-applications/

    JWTs are bits of information passed to a REST service to gain access to secured resources.   Any client that has the JWT can access the secured resource. 

    Are you receiving an error message while trying to access a secured resource? Can you share the client code?

    Maybe all you need to do is add the [Authorize] attribute to a Web API action or controller according to the official documentation?

    If you are trying to secure a web application like MVC or Razor Pages the you are using the wrong approach and should use standard cookie authentication.  https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-5.0

    Wednesday, December 30, 2020 9:06 PM
  • User-544325736 posted

    So what I am trying to do is

    I have a web api it creates a token and sends it back to my MVC project.

    I want this token to authenticate a page in my mvc project,

    that is my last part to understand and then for all pages in my mvc project to be authenticated do i need to hold onto this JWT in something for this?

    I'm working on graspin this concept been researching for hours but i dont fully have it yet.

    I have 2 projects a web api and a MVC UI,

    my token and CRUD is all done in the API.

    only the GUI is on the mvc project.

    i guess i dont fully understand how this works yet with authenticating the user with my token recev from the api

    Here is my client code.

    //home controller
     [Authorize]
            public IActionResult Success()
            {
                return View();
            }
    
            public IActionResult Failure()
            {
                return View();
            }
    
    // user controller
     public IActionResult Login()
            {
                return View();
            }
            [HttpPost]
            public async Task<IActionResult> Login(LoginModel loginModel)
            {
                if (ModelState.IsValid)
                {
                    var model = JsonConvert.SerializeObject(loginModel);
                    var client = apiClient.CreateClient();
    
                    HttpRequestMessage httpRequest = new HttpRequestMessage
                    {
                        Content = new StringContent(model, Encoding.UTF8, "application/json"),
                        RequestUri = new Uri($"https://localhost:5001/api/Account/Authenticate"),
                        Method = new HttpMethod("Post")
                    };
    
                    var response = await client.SendAsync(httpRequest);
                    if (response.IsSuccessStatusCode)
                    {
                        return View("Success");
                    }
                }
    
                return View("Failure");
            }

    Wednesday, December 30, 2020 10:23 PM
  • User475983607 posted

    Pretty simple as explained above.  Web application like MVC use cookie authentication.  Create the authentication cookie after a successful token authentication.  Read the linked documentation in my first post as it illustrates how to configure cookie authentication and create a cookie.

    The result of a successful token authentication is a token.  Store the token somewhere, Session cookie, database, any standard MVC state management should work.  You'll need the token when making API requests.  Simply add the token to the bearer header when making the API request. 

    Wednesday, December 30, 2020 11:01 PM
  • User1686398519 posted

    Hi ExceedingLife, 

    The JWT token is returned to the client application which must include it in the HTTP Authorization header of subsequent requests to secure routes.

    You can click this link to view ASP.NET Core 3.1-JWT Authentication Tutorial with Example API.

    Best Regards,

    YihuiSun

    Thursday, December 31, 2020 10:40 AM
  • User-474980206 posted

    How is you UI server going to store the jwt tokens by user? The UI server needs its own authorization system, typically cookie based. When token expires, how is the UI going to get a new one? Will the user have to login again. Can it refresh the the token?

    note: validation of jwt token referees to validating the checksum, audience and issuer, or whether it’s expired.

    Thursday, December 31, 2020 5:20 PM
  • User-544325736 posted

    would this also work with roles?

    I was looking and it would, I would just put it in a claim.

    So I make a new claim for the role. I had the token with the claims in it to a cookie and then I read the cookie and put it in the bearer header. 

    How do I do this with a separate project? my API creates the token and sends it back to my  UI.

    that is my question how do I use with with the UI?

    do I use the jwt same code from my API in the UI as well?

                //Add Authentication
                var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]));
                services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                }).AddCookie()
                .AddJwtBearer(config =>
                {
                    config.RequireHttpsMetadata = false;
                    config.SaveToken = true;
                    config.TokenValidationParameters = new TokenValidationParameters()
                    {
                        IssuerSigningKey = signingKey,
                        ValidateAudience = true,
                        ValidAudience = this.Configuration["Tokens:Audience"],
                        ValidateIssuer = true,
                        ValidIssuer = this.Configuration["Tokens:Issuer"],
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true
                    };
                });

    Thursday, December 31, 2020 7:21 PM
  • User475983607 posted

    would this also work with roles?

    I was looking and it would, I would just put it in a claim.

    So I make a new claim for the role. I had the token with the claims in it to a cookie and then I read the cookie and put it in the bearer header. 

    How do I do this with a separate project? my API creates the token and sends it back to my  UI.

    that is my question how do I use with with the UI?

    do I use the jwt same code from my API in the UI as well?

    Return the user's claims along with the token.  Add the claims to the authentication cookie as clearly and openly illustrated in the linked documentation.

    You might consider using an existing OAuth/OIDC service rather than writing your own.  I recommend learning IdentityServer4.

    Thursday, December 31, 2020 10:09 PM
  • User-544325736 posted

    Thank you,

    That is what i plan on teaching myself in the soon future. IdentityServer4.

    For the short term I have a quick question, I create my token in my API and send it to the front end. On my front end I have a page that I only want authorized users to visit. this has no connection with the API.

    I put [authorize] in the controller but it doesn't know anything.

    Do I have to setup my same JWT settings on the front end as the back end?

    or would I make some kind of validatetoken method on the front end and then if that passes the user can visit the restricted page.

    I'm not sure about this situation.

    In my controller its just a simple return view action. how would I set up a bearer token request in an action like that or would I have to use httpclientfactory and make a whole request and add the bearer to that?

    I'm very interested in knowing this. How to use front end authentication when token comes from back end. 

    Thanks for everything so far!

    Friday, January 1, 2021 4:00 AM
  • User-474980206 posted

    Browsers don’t support sending bearer tokens. In your case the jwt bearer tokens and roles are for the webapi server which the UI server is calling. unless your UI server is hosting a SPA which can send bearer tokens via Ajax calls, they are little use for any UI servers authentication. 

    Friday, January 1, 2021 4:26 AM
  • User475983607 posted

    I've explained several times, MVC applications use cookie authentication not JWTs. 

    As far as I can tell, you made your mind on how JWTs work and you do not want to accept the advice given on the forum or openly published reference documentation.  I do not know how to make this concept any clearer.

    Friday, January 1, 2021 1:09 PM
  • User-544325736 posted

    Thanks again for the knowledge,

    So I been messing around with this for awhile now. On Postman I got a 200. I can take my token sent from my API, if I could somehow put it as a bearer token in my action before calling my next view it will authorize my user and would be a success.

    Is there such a thing where I can insert a bearer token before calling Return View() or return RedirectToAction().

    Here is some stuff I have tried but I have not found the right method to do this yet.

    [HttpPost]
            public async Task<IActionResult> Login(LoginModel loginModel)
            {
                if (ModelState.IsValid)
                {
                    var model = JsonConvert.SerializeObject(loginModel);
                    var client = apiClient.CreateClient();
    
                    HttpRequestMessage httpRequest = new HttpRequestMessage
                    {
                        Content = new StringContent(model, Encoding.UTF8, "application/json"),
                        RequestUri = new Uri($"https://localhost:5001/api/Account/Authenticate"),
                        Method = new HttpMethod("Post")
                    };
    
                    var response = await client.SendAsync(httpRequest);
                    if (response.IsSuccessStatusCode)
                    {
                        var jsonResponse = await response.Content.ReadAsStringAsync();
                        var z = response.Content.ReadFromJsonAsync<string>();
                        var y = response.Content.ToString();
    
                        var jro = JObject.Parse(jsonResponse);
                        var token = jro["token"];
                        Console.WriteLine(token);
                        Console.WriteLine(token.ToString());
                        HttpContext.Items["access_token"] = token;
                        HttpContext.Request.Headers.Add("Bearer", token.ToString());
                        // var token = JsonConvert.DeserializeObject(x);
                        //HttpContext.Request.Headers ="Bearer" + response;
                        // HttpContext.User.Identity.IsAuthenticated;
    
                        return RedirectToAction("Success","Home",null);
                    }
                }
    
                return View("Failure");
            }

    in my var token

    I get the token that is needed to be entered as a Bearer in my request.

    I also tried reading it on the other page side.

            [Authorize]
            public async Task<IActionResult> Success()
            {
                await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
                 HttpContext.Request.Headers.ContainsKey("Bearer");
                var x = HttpContext.Items["access_token"];
                return View();
            }

    Sunday, January 3, 2021 4:49 AM
  • User475983607 posted

    ExceedingLife

    Is there such a thing where I can insert a bearer token before calling Return View() or return RedirectToAction().

    No.   A View does not have a bearer token.  Similarly, a redirect is an HTTP response returned to the browser.  The browser is not looking for a bearer token in a redirect and does forward the token.

    Below is an example of how this could work in an MVC application.  Again, the key is using cookie authentication.  

    Model passed between Web API and MVC.

        public class LoginResponse
        {
            public string token { get; set; }
            public List<ClaimDto> claims { get; set; }
            public string role { get; set; }
        }
    
        public class ClaimDto
        {
            public string type { get; set; }
            public string value { get; set; }
        }

    Web API.  The AuthenticateMvc method just populates the LoginResponse.

    //POST: /Account/AuthenticateMvc
    [AllowAnonymous]
    [HttpPost("authenticatemvc")]
    public IActionResult AuthenticateMvc([FromBody] LoginModel model)
    {
        LoginResponse result = _authService.AuthenticateMvc(model.Username, model.Password);
    
        if (result == null || string.IsNullOrEmpty(result.token))
        {
            return BadRequest(new { message = "Username or password is incorrect" });
        }
        return Ok(result);
    }

    On the client MVC application I created a basic service that calls the Web API authentication endpoint and deserialize the response.

        public interface ICustomAuthenticateService
        {
            Task<LoginResponse> Authenticate(LoginRequest login);
        }
    
        public class CustomAuthenticateService : ICustomAuthenticateService
        {
            private readonly IHttpClientFactory _clientFactory;
            public CustomAuthenticateService(IHttpClientFactory clientFactory)
            {
                _clientFactory = clientFactory;
            }
    
            public async Task<LoginResponse> Authenticate(LoginRequest login)
            {
                var json = new StringContent(
                    JsonSerializer.Serialize(login),
                    Encoding.UTF8,
                    "application/json");
    
                HttpClient client = _clientFactory.CreateClient("CustomAuthentication");
                using HttpResponseMessage response = await client.PostAsync("Account/AuthenticateMvc", json);
                {
                    string res = await response.Content.ReadAsStringAsync();
                    response.EnsureSuccessStatusCode();
                    using (var responseStream = await response.Content.ReadAsStreamAsync())
                    {
                        return await JsonSerializer.DeserializeAsync<LoginResponse>(responseStream);
                    }
                }
    
            }
        }

    Authentication cookie and service registration.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options => {
                options.LoginPath = "/Account/Index";
                options.ExpireTimeSpan = TimeSpan.FromSeconds(10);
                options.SlidingExpiration = true;
                });
    
        services.AddHttpClient("CustomAuthentication", c =>
        {
            c.BaseAddress = new Uri("https://localhost:44355/");
            c.DefaultRequestHeaders.Add("Accept", "application/json");
        });
    
        services.AddScoped<ICustomAuthenticateService, CustomAuthenticateService>();
    }

    MVC Implementation.

    public class AccountController : Controller
        {
            private readonly ICustomAuthenticateService _authService;
            public AccountController(ICustomAuthenticateService authSerivce)
            {
                _authService = authSerivce;
            }
    
            public IActionResult Index()
            {
                return View();
            }
    
            [HttpPost]
            public async Task<IActionResult> Login(LoginRequest login)
            {
                //Authenticate with web API
                LoginResponse results = await _authService.Authenticate(login);
    
                List<Claim> claims = new List<Claim>();
                foreach(var c in results.claims)
                {
                    claims.Add(new Claim(c.type, c.value));
                }
                //Added the token to the cliams collection.  
                //I'm not sure where you want to persist the token
                claims.Add(new Claim("token", results.token));
                //Also adding the role, "User", to the claims.  
                //I'm not sure if you are using roles
                claims.Add(new Claim(ClaimTypes.Role, results.role));
    
                var claimsIdentity = new ClaimsIdentity(
                    claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
                var authProperties = new AuthenticationProperties
                {
                    //AllowRefresh = <bool>,
                    // Refreshing the authentication session should be allowed.
    
                    ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
                    // The time at which the authentication ticket expires. A 
                    // value set here overrides the ExpireTimeSpan option of 
                    // CookieAuthenticationOptions set with AddCookie.
    
                    IsPersistent = false,
                    // Whether the authentication session is persisted across 
                    // multiple requests. When used with cookies, controls
                    // whether the cookie's lifetime is absolute (matching the
                    // lifetime of the authentication ticket) or session-based.
    
                    //IssuedUtc = <DateTimeOffset>,
                    // The time at which the authentication ticket was issued.
    
                    //RedirectUri = <string>
                    // The full path or absolute URI to be used as an http 
                    // redirect response value.
                };
    
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    new ClaimsPrincipal(claimsIdentity),
                    authProperties);
    
                return RedirectToAction("Index", "Home");
            }
        }

    Login View

    <form asp-action="Login">
        <div>
            <input name="Username" type="text" value="username" />
        </div>
        <div>
            <input name="Password" type="text" value="password" />
        </div>
        <div>
            <input id="Submit1" type="submit" value="submit" />
        </div>
    </form>

    Home/Index View that displays the claims.

    <h2>Claims</h2>
    
    <dl>
        @foreach (var claim in User.Claims)
        {
            <dt>@claim.Type</dt>
            <dd>@claim.Value</dd>
        }
    </dl>

    Results

    Claims
    http://schemas.microsoft.com/ws/2008/06/identity/claims/role
    UserRole
    http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
    email@email.com
    token
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IjEiLCJuYmYiOjE2MDk2ODcxOTEsImV4cCI6MTYxMDI5MTk5MSwiaWF0IjoxNjA5Njg3MTkxLCJpc3MiOiJJc3N1ZXIiLCJhdWQiOiJBdWRpZW5jZSJ9.M18S5qwDHFmYdrlPmBJD0-RJ5O_4Z963_S3T63YpH04
    http://schemas.microsoft.com/ws/2008/06/identity/claims/role
    User

    Make an effort to read the linked documentation and learn the basics.  

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, January 3, 2021 3:40 PM
  • User-544325736 posted

    Thank you mgebhard,

    I will look into cookie authentication. and look at what you posted to make it work with my project.

    This is my first time doing auth from an API. my first microservice I am working on.

    Sunday, January 3, 2021 4:59 PM
  • User475983607 posted

    This is my first time doing auth from an API. my first microservice I am working on.

    I think it is important to understand your problem statement has nothing to do with microservices.  You're struggling with browser and MVC security fundamentals.   

    MVC Security using an Authentication Cookie.

    https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-5.0

    Microservice Security.

    https://docs.microsoft.com/en-us/dotnet/architecture/microservices/secure-net-microservices-web-applications/

    I recommend taking the time to educate yourself and use standard libraries rather than building your own.  

    Sunday, January 3, 2021 5:27 PM
  • User-544325736 posted

    Thank you so much mgebhard for that detailed example answer! that worked with my application! 

    I am going to continue learning about this and I want to use IdentityServer4 when I release my site.

    I also plan adding roles in the future.

    So the way you answered it, would that be acceptable to use on a website?

    People wouldn't be able to get pass the validation if I use forgery tokens and etc.

    I plan on using IdentityServer4 but I was wondering if I could use something like this first and upgrade to that.

    1 question that I also have, so the JWT token is pointless using this method? Do I use JWT when I have different APIs and to connect to a different API I set a bearer request with the token?

    Than in the different APIs I  set the

    services.AddAuthentication(options =>
               {
                   options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                   options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
               });
                .AddJwtBearer(config =>
    ...

    all the same. so each one can have authorized and they will be successful with the token created when the user logs in.

    Is that how that works?

    Monday, January 4, 2021 2:32 AM