locked
Get Jwt Token from form-urlencoded RRS feed

  • Question

  • User-588203678 posted

    Hi,

    I need to create a Asp.net core Web Api that accepts the following key and  value pair as shown below and generate JWT access token 

    "userId": "0302",
    "password": "0A4E719A0D3E52D0F1B287843D57D5BCBDF73FCA",
    "stationId" :"1",
    "applicationId" : 100,
    "client_id" : "xamarin",
    "client_secret":"secret",
    "grant_type":"password"

    Anand

    Friday, July 3, 2020 1:42 PM

All replies

  • User475983607 posted

    Your question indicates that you need to learn OAuth/OIDC and/or read the documentation that comes with the token server you are using.  

    If you need a token server then I recommend IdentityServer4; https://identityserver4.readthedocs.io/en/latest/

    If you are building a token server from scratch then I recommend hiring someone to help you.

    Friday, July 3, 2020 2:19 PM
  • User-588203678 posted

    Hi

    From Key and Value pair I need to generate the JWT token. the url shown does not provide those.

    Guhan

    Friday, July 3, 2020 2:36 PM
  • User475983607 posted

    guhananth1

    From Key and Value pair I need to generate the JWT token. the url shown does not provide those.

    You do not understand the technology.  Placing these values in the URL negates the security.  Typically, the authenticating is a two step process where the client is redirected to the token server.   I recommend that you hire someone to help you or make an effort to learn the fundamentals. 

    Friday, July 3, 2020 2:58 PM
  • User-474980206 posted

    in a jwt identity token the name / value pairs are typically claims. if you just want a generic jwt token. try:

      https://github.com/jwt-dotnet/jwt

    Friday, July 3, 2020 3:18 PM
  • User-588203678 posted

    MgeBhard

    I have create another ActionResult as

     [HttpPost]
            [Route("Login")]
            public IActionResult Login(Users userModel)
            {
                string baseUrl = "http://localhost:5125";
                HttpClient client = new HttpClient();
                client.BaseAddress = new Uri(baseUrl);
                var contentType = new MediaTypeWithQualityHeaderValue("application/json");
                client.DefaultRequestHeaders.Accept.Add(contentType);
    
                //User userModel = new User();
                userModel.userName = "superadmin";
                userModel.password = "bck";
                userModel.client_id = "xamarin";
                userModel.client_secret = "secret";
                userModel.grant_type = "password";
    
                string stringData = JsonConvert.SerializeObject(userModel);
                var contentData = new StringContent(stringData,System.Text.Encoding.UTF8, "application/json");
    
                HttpResponseMessage response = client.PostAsync("/api/Token/Login", contentData).Result;
                string stringJWT = response.Content. ReadAsStringAsync().Result;
               
                JWT jwt = JsonConvert.DeserializeObject<JWT>(stringJWT);
    
                HttpContext.Session.SetString("token", jwt.Token);
    
                // ViewBag.Message = "User logged in successfully!";
    
                return Ok(response);
    
            }
            public class JWT
            {
                public string Token { get; set; }
            }

    Saturday, July 4, 2020 6:27 PM
  • User475983607 posted

    guhananth1

    I have create another ActionResult as

    Do you have a question? Problem?

    The clientId and secret identify a web server application registered with the token server.   It looks like you are trying to mimic a browser's interaction with a token server using C#.  This is the wrong approach. 

    Unfortunately, when you share code so poorly designed it make it difficult to understand the intent.  Are you trying to secure a Xamarin application?  Secure Web API?  Both?  Are you using an existing token server?  Do you need a token server? 

    Saturday, July 4, 2020 7:37 PM
  • User-588203678 posted

    I am passing these values in postman.it create Jwt token.iwant to do the same in c # code.it is secure web api
    Saturday, July 4, 2020 9:07 PM
  • User-474980206 posted

    Then show the postman configuration and post values and headers. If you used postman’s authorization helper, then you a missing a lot of code.

    Saturday, July 4, 2020 10:00 PM
  • User475983607 posted


    I am passing these values in postman.it create Jwt token.iwant to do the same in c # code.it is secure web api

    Unless you wrote the token server I doubt the PostMan test actually works.  If you wrote the token server then you would not be asking this question.

    Saturday, July 4, 2020 10:16 PM
  • User-588203678 posted
    What is remedy to get Jwt token through coding. Please share the code using urlencoded values.
    Sunday, July 5, 2020 1:44 AM
  • User475983607 posted

    What is remedy to get Jwt token through coding. Please share the code using urlencoded values.

    The remedy is taking the time to learn the fundamentals rather than making assumptions of how OAuth works.

    I built a simple token server example below.  You'll notice there's no clientId.  That's because the clientId (and secret) are used to register/identify a web application with a remote token server.  The secret is used to sign the token.  If you are authenticating with a remote token server then it is up to you to read the documentation that comes with the service or contact support for the service.  The community CANNOT help you with an unknown 3rd party service.

    Authentication service

     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);
            }
        }

    Configuration

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

    Register service in startup

     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,
                    };
                    x.Events = new JwtBearerEvents
                    {
                        OnAuthenticationFailed = context =>
                        {
                            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                            {
                                context.Response.Headers.Add("Token-Expired", "true");
                            }
                            return Task.CompletedTask;
                        }
                    };
                });
    
                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();
                });
            }
        }

    Web API Token controller

        [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);
            }
        }

    Token URL; https://localhost:44355/Account/authenticate

    Login model

    {
    	"username": "username",
    	"password": "password"
    }

    Secured resource

        [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();
            }
        }

    Sunday, July 5, 2020 12:10 PM