Posted on 28/02/2026 14:05:25
Hi Jon
The example on the doc site has the wrong URL - and describes overrriding expiration wrong. Below is a better script.
// Accept default (1800s):
const response = await fetch('/dwapi/users/token', {
method: 'POST',
credentials: 'include'
});
// Custom expiration:
const response = await fetch('/dwapi/users/token?expirationInSeconds=3600', {
method: 'POST',
credentials: 'include'
});
Register your custom API assembly and use permissionfilter
Your assembly with your custom api endpoint needs a class implementing both `IPipeline` and `IWebApi`. The `WebApiPipeline` automatically discovers all `IWebApi` assemblies at startup and adds them as MVC application parts --- so just implementing the interface is enough:
```
using Dynamicweb.Extensibility.AddIns;
using Dynamicweb.Host.Core;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
[AddIn]
public class MyApiPipeline : IPipeline, IWebApi
{
public int Rank => 200; // must be > 100 to run after built-in DW pipelines
public void RegisterServices(IServiceCollection services, IMvcCoreBuilder mvcBuilder) { }
public void RegisterApplicationComponents(IApplicationBuilder app) { }
public void RunInitializers() { }
}
```
Create your controller
Reference `Dynamicweb.Frontend.Classic.Api` and apply `[PermissionFilter]` to endpoints that need an authenticated user:
```
using Dynamicweb.Frontend.Classic.Api;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("dwapi/myapi")]
public class MyApiController : ControllerBase
{
[HttpGet("data")]
[PermissionFilter] // requires valid JWT in Authorization: Bearer header
public IActionResult GetData()
{
// HttpContext.User is populated by UserTokenFilter (base of PermissionFilter)
// DW PermissionContext is also set, so DW permission checks work normally
return Ok(new { message = "hello" });
}
}
```
What `PermissionFilter` actually does
The chain is:
```
PermissionFilter
└─ UserTokenFilter (base)
└─ reads Authorization: Bearer <token> header
└─ validates JWT via JwtService.GetPrincipal()
└─ sets HttpContext.User from claims
└─ resolves DW User from claims
└─ sets PermissionContext.FrontendUserContext(user) on HttpContext.Items
└─ so DW's built-in permission checks work within the request scope
```