I create a .net core api which will send a jwtsecuritytoken to client. Connected user to use a functionality of the application have to have a token for each functionality, this token have an expiration date of 5 minutes for exemple and the token have to
be refresh after his expiration (if there is no error).
I start to code something but I don't know how to do the refresh of my token ?
[Route("api/[controller]")]
[ApiController]
public class TokenController : ControllerBase
{
private string GenerateToken(string username)
{
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("ijustwanttotestsomething"));
Claim[] claims = new Claim[]
{
new Claim(ClaimTypes.Name , username)
};
Console.WriteLine(DateTime.Now);
JwtSecurityToken jwt = new JwtSecurityToken(
claims: claims,
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddMinutes(5),
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
);
return new JwtSecurityTokenHandler().WriteToken(jwt);
}
[HttpPost]
public ActionResult<string> Create(string username)
{
return GenerateToken(username);
}
[HttpGet]
public ActionResult<JwtSecurityToken> TokenExpired (string token)
{
var stream = token ;
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(stream);
JwtSecurityToken tokenS = handler.ReadToken(stream) as JwtSecurityToken;
DateTime dateTimeToken = DateTime.UtcNow;
if (dateTimeToken > tokenS.ValidTo)
return BadRequest("EXPIRED");
return Ok(tokenS);
}
[HttpGet("[Action]")]
public ActionResult<JwtSecurityToken> RefreshToken (string token)
{
// CODE SOMETHING
}
}
I try something but I have an error, it's a problem with addDeveloperSigningCredential().
Do you know how can I have another GrantTypes for my project for example the user can have a token thinks to a string which can be "test" or something like that?
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
public class Config
{
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("TRACEITLMAPI","TRACE-it LicenseManager WebAPI")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "TRACEITLMAPI" }
}
};
}
}
Do you know how can I have another GrantTypes for my project for example the user can have a token thinks to a string which can be "test" or something like that?
I'm not sure what you are asking or what problem you are trying to solve.
[HttpGet]
public async Task<IActionResult> Get()
{
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5001");
if (disco.IsError)
{
return new JsonResult(disco.Error);
}
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
Scope = "TestSMTH"
});
if (tokenResponse.IsError)
{
return new JsonResult(tokenResponse.Error);
}
Console.WriteLine(tokenResponse.Json);
Console.WriteLine("\n\n");
System.Threading.Thread.Sleep(12000);
Console.WriteLine(tokenResponse.AccessToken);
Console.WriteLine("> 10secs");
return new JsonResult(tokenResponse);
}
in my api startup
public void ConfigureServices(IServiceCollection services)
{
string conn = Environment.GetEnvironmentVariable("connectionString");
services.AddEntityFrameworkNpgsql().AddDbContext<DBContext>(opt => opt.UseNpgsql(conn));
services.AddCors(options =>
{
options.AddPolicy("AnyOrigin", builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
services.AddAuthentication("Bearer").AddJwtBearer("Bearer", o =>
{
o.Authority = "http://localhost:5001";
o.Audience = "TestSMTH";
o.RequireHttpsMetadata = false;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSwaggerGen(
c => {
c.SwaggerDoc("v1", new Info { Title = "WEBAPI", Version = "v1 " });
}
);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseAuthentication();
//app.UseAuthorization();
app.UseCors("AnyOrigin");
app.UseSwagger();
app.UseSwaggerUI(c => {
c.SwaggerEndpoint("/swagger/v1/swagger.json", "WEBAPI");
c.RoutePrefix = string.Empty;
});
app.UseMvc();
}
And in the project which send the token
public class Config
{
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("TestSMTH","ProjectWEBAPI")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "TestSMTH" },
AccessTokenLifetime = 10
}
};
}
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
My issue is first case I don't know how to test the expiration of my token or second case my token expiration doesn't work.
And I don't know how with my project it will work because the client will ask the webapi a token the webapi will see if he can send the token if the api can't send the token because there is already an active token for the asked functionality he won't send
it. I think I don't understand ow it works to i'm strucked.
My issue is first case I don't know how to test the expiration of my token or second case my token expiration doesn't work.
I'm not sure I understand the problem and I assume you are implementing IdentityServer4. You get to set the token expiration in the token server configuration. I'm not sure why you do not know the expiration or why the expiration cannot be passed down
to the client.
The IdentityServer4 quick start tutorial specially shows how to display the token with includes the expiration (exp).
And I don't know how with my project it will work because the client will ask the webapi a token the webapi will see if he can send the token if the api can't send the token because there is already an active token for the asked functionality he won't send
it. I think I don't understand ow it works to i'm strucked.
The client is responsible for managing the token and using a refresh token if needed. Again, I recommend taking the time to go through the quick start tutorial.
Member
5 Points
23 Posts
How can I refresh my jwtsecuritytoken in my project?
Nov 18, 2019 12:33 PM|soleyne|LINK
I create a .net core api which will send a jwtsecuritytoken to client. Connected user to use a functionality of the application have to have a token for each functionality, this token have an expiration date of 5 minutes for exemple and the token have to be refresh after his expiration (if there is no error).
I start to code something but I don't know how to do the refresh of my token ?
All-Star
53001 Points
23587 Posts
Re: How can I refresh my jwtsecuritytoken in my project?
Nov 18, 2019 12:44 PM|mgebhard|LINK
I recommend using an existing token server rather than building your own. See IdentityServer4 which is part of the ASP.NET Core 3.0 templates.
http://docs.identityserver.io/en/latest/
If you want to build a custom solution then take time to learn OAuth/OIDC specifications.
Member
5 Points
23 Posts
Re: How can I refresh my jwtsecuritytoken in my project?
Nov 18, 2019 02:55 PM|soleyne|LINK
I try something but I have an error, it's a problem with addDeveloperSigningCredential().
Do you know how can I have another GrantTypes for my project for example the user can have a token thinks to a string which can be "test" or something like that?
All-Star
53001 Points
23587 Posts
Re: How can I refresh my jwtsecuritytoken in my project?
Nov 18, 2019 03:23 PM|mgebhard|LINK
I'm not sure what you are asking or what problem you are trying to solve.
The IdentityServer4 documentation has a step-by-step tutorial that you should go through; http://docs.identityserver.io/en/latest/quickstarts/0_overview.html. Also, expect to spend a few weeks learning OAuth/OIDC and building demo token server configurations.
Member
5 Points
23 Posts
Re: How can I refresh my jwtsecuritytoken in my project?
Nov 20, 2019 04:32 PM|soleyne|LINK
I try this, in my api
in my api startup
And in the project which send the token
My issue is first case I don't know how to test the expiration of my token or second case my token expiration doesn't work.
And I don't know how with my project it will work because the client will ask the webapi a token the webapi will see if he can send the token if the api can't send the token because there is already an active token for the asked functionality he won't send it. I think I don't understand ow it works to i'm strucked.
All-Star
53001 Points
23587 Posts
Re: How can I refresh my jwtsecuritytoken in my project?
Nov 20, 2019 06:46 PM|mgebhard|LINK
I'm not sure I understand the problem and I assume you are implementing IdentityServer4. You get to set the token expiration in the token server configuration. I'm not sure why you do not know the expiration or why the expiration cannot be passed down to the client.
The IdentityServer4 quick start tutorial specially shows how to display the token with includes the expiration (exp).
http://docs.identityserver.io/en/latest/quickstarts/1_client_credentials.html
https://tools.ietf.org/html/rfc7519#section-4.1.4
The client is responsible for managing the token and using a refresh token if needed. Again, I recommend taking the time to go through the quick start tutorial.
http://docs.identityserver.io/en/latest/quickstarts/0_overview.html
If you are building a custom token server then it is up to you to do the research.