locked
how to use bearer auth token in asp.net core application RRS feed

  • Question

  • User2097725413 posted

    Hi

    I have two websites, one website gives/generates a bearer token, and using that token need to call other api services.

    Another application is asp.net core web application, which will communicate to the above API site and generates bearer auth token and will store the token and will pass the token in each request to API site.

    To develop the web application, I have the following questions

    1) On login action where I can store the bearer token and how to set it at Authorize/Authenticate attribute, so that I can use it at all controller.

    2)How to access the stored token and pass it to in header attribute at each service level, i.e in Services, from where I will get the stored token so that I will pass it API.

    Can someone please guide me on how to implement it with a sample of code.

    Thanks,

    Uday Mahajan

    Thursday, September 3, 2020 8:00 AM

All replies

  • User475983607 posted

    1) On login action where I can store the bearer token and how to set it at Authorize/Authenticate attribute, so that I can use it at all controller.

    Frankly, this information is openly published on the Internet that you can find with a simple Google search.

    Startup.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.Json.Serialization;
    using System.Threading.Tasks;
    using ApiJwtDemo.Service;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.HttpsPolicy;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using Microsoft.IdentityModel.Tokens;
    using Microsoft.OpenApi.Models;
    
    namespace ApiJwtDemo
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers()
                    .AddJsonOptions(o => o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
    
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
                });
             
                var secret = Encoding.ASCII.GetBytes(Configuration["JwtConfig:secret"]);
                services.AddAuthentication(x =>
                {
                    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(x =>
                {
                    x.RequireHttpsMetadata = false;
                    x.SaveToken = true;
                    x.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(secret),
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidIssuer = "Issuer",
                        ValidAudience = "Audience",
                        ClockSkew = TimeSpan.Zero,
                    };
                });
    
                services.AddScoped<IApplicationUser, ApplicationUser>();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment()) 
                {            
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseHttpsRedirection();
    
                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                });
    
                app.UseRouting();
    
                app.UseAuthentication();
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }
        }
    }
    

    Appsetting.json

    {
      "jwtConfig": {
        "Secret": "A super secret string that can be wahtever you like"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      }
    }
    

    Login model

        public class LoginModel
        {
            [JsonPropertyName("UserName")]
            public string Username { get; set; }
            [JsonPropertyName("Password")]
            public string Password { get; set; }
        }

    Login service registered in startup.

    using Microsoft.Extensions.Configuration;
    using Microsoft.IdentityModel.Tokens;
    using System;
    using System.Collections.Generic;
    using System.IdentityModel.Tokens.Jwt;
    using System.Linq;
    using System.Security.Claims;
    using System.Text;
    using System.Threading.Tasks;
    using ApiJwtDemo.Models;
    
    namespace ApiJwtDemo.Service
    {
        public interface IApplicationUser
        {
            string Authenticate(string username, string password);
        }
    
        public class ApplicationUser : IApplicationUser
        {
            private readonly IConfiguration Configuration;
            public ApplicationUser(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            private List<User> _users = new List<User>
            {
                new User { Id = 1, FirstName = "Hello", LastName = "World", Username = "username", Password = "password" }
            };
    
            public string Authenticate(string username, string password)
            {
                var user = _users.SingleOrDefault(x => x.Username == username && x.Password == password);
    
                // return null if user not found
                if (user == null)
                    return null;
    
                // authentication successful so generate jwt token
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes(Configuration["JwtConfig:secret"]);
                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(new Claim[]
                    {
                        new Claim(ClaimTypes.Name, user.Id.ToString()),
                    }),
                    IssuedAt= DateTime.UtcNow,
                    Expires = DateTime.UtcNow.AddDays(7),
                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
                    Issuer = "Issuer",
                    Audience = "Audience"
                };
                var token = tokenHandler.CreateToken(tokenDescriptor);
                return tokenHandler.WriteToken(token);
            }
        }
    
    
    }

    Login controller

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using ApiJwtDemo.Models;
    using ApiJwtDemo.Service;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ApiJwtDemo.Controllers
    {
        [Authorize]
        [ApiController]
        [Route("[controller]")]
        public class AccountController : ControllerBase
        {
            private readonly IApplicationUser _authService;
            public AccountController(IApplicationUser authSerice)
            {
                _authService = authSerice;
            }
    
            [AllowAnonymous]
            [HttpPost("authenticate")]
            public IActionResult Authenticate([FromBody]LoginModel model)
            {
                string token = _authService.Authenticate(model.Username, model.Password);
    
                if (string.IsNullOrEmpty(token))
                {
                    return BadRequest(new { message = "Username or password is incorrect" });
                }
                return Ok(token);
            }
        }
    }

    Secured controller

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    
    namespace ApiJwtDemo.Controllers
    {
        [Authorize]
        [ApiController]
        [Route("[controller]")]
        public class WeatherForecastController : ControllerBase
        {
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
    
            private readonly ILogger<WeatherForecastController> _logger;
    
            public WeatherForecastController(ILogger<WeatherForecastController> logger)
            {
                _logger = logger;
            }
    
            [HttpGet]
            public IEnumerable<WeatherForecast> Get()
            {
                var rng = new Random();
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                })
                .ToArray();
            }
        }
    }
    

    2)How to access the stored token and pass it to in header attribute at each service level, i.e in Services, from where I will get the stored token so that I will pass it API.

    Depends on the type of client application you are building.  

    Thursday, September 3, 2020 10:16 AM