Skip to main content
All docs
V23.2

Configure the JWT Authentication for the Web API

  • 5 minutes to read

Enable Authentication in a New Project

Use the Solution Wizard to create a Web API project with the JWT authentication. If you choose Standard authentication on the Choose Security page, the wizard generates JWT authentication scaffolding code.

Enable the JWT authentication

You can replace the autogenerated IssuerSigningKey value with your JWT signing key and change other JWT settings in the appsettings.json file. We recommend that you use the Secret Manager tool to store the signing key. You can store it in the appsettings.json file for testing purposes only.

File: MySolution.WebApi\appsettings.json (MySolution.Blazor.Server\appsettings.json)

// ...
"Authentication": {
    "Jwt": {
    "Issuer": "My",
    "Audience": "http://localhost:4200",
    "IssuerSigningKey": "c1d2e0a7-405b-40be-9b36-fa93469b673a"
    }
}    
// ...

See the following section for information on how to test the JWT authentication: Use the Swagger UI to Test the JWT Authentication.

Enable Authentication in an Existing Project

To add the JWT authentication to an existing Web API or Blazor Server project, follow the steps below.

Step 1. Install the Required NuGet Packages

Install the following NuGet packages to the MySolution.WebApi (MySolution.Blazor.Server) and MySolution.Module projects:

  • DevExpress.ExpressApp.Security.AspNetCore
  • Microsoft.AspNetCore.Authentication.JwtBearer
  • DevExpress.ExpressApp.Security.Xpo - in XPO applications
  • DevExpress.EntityFrameworkCore.Security - in EF Core applications

See the following topic for details: Choose Between Offline and Online DevExpress NuGet Feeds.

Step 2. Modify appsettings.json

Add the Jwt option to the Authentication section in the appsettings.json file.

File: MySolution.WebApi\appsettings.json (MySolution.Blazor.Server\appsettings.json)

// ...
"Authentication": {
    "Jwt": {
    "Issuer": "My",
    "Audience": "http://localhost:4200",
    "IssuerSigningKey": "c1d2e0a7-405b-40be-9b36-fa93469b673a"
    }
},    
// ...

The IssuerSigningKey value is an autogenerated key. You can replace it with your JWT signing key. You can store it in the appsettings.json file for testing purposes only. We recommend that you use the Secret Manager tool to store the signing key.

Step 3. Modify Startup.cs

Add the following code to the ConfigureServices method to enable authentication:

File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)

using DevExpress.ExpressApp.Security;
using DevExpress.Persistent.BaseImpl.PermissionPolicy;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
// ...
public void ConfigureServices(IServiceCollection services) {
    //...
    services.AddXafAspNetCoreSecurity(Configuration, options => {
        options.RoleType = typeof(PermissionPolicyRole);
        options.UserType = typeof(MySolution.Module.BusinessObjects.ApplicationUser);
        options.UserLoginInfoType = typeof(MySolution.Module.BusinessObjects.ApplicationUserLoginInfo);
        // in XPO applications, uncomment the following line
        // options.Events.OnSecurityStrategyCreated = securityStrategy => ((SecurityStrategy)securityStrategy).RegisterXPOAdapterProviders();
        options.SupportNavigationPermissionsForTypes = false;
    })
    .AddAuthenticationStandard(options => {
        options.IsSupportChangePassword = true;
    });
    var authentication = services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme);
    // The AddJwtBearer method adds JWT credentials to the XAF authentication. 
    authentication
        .AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters() {
                ValidIssuer = Configuration["Authentication:Jwt:Issuer"],
                ValidAudience = Configuration["Authentication:Jwt:Audience"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:Jwt:IssuerSigningKey"]))
            };
        });
    services.AddAuthorization(options => {
        options.DefaultPolicy = new AuthorizationPolicyBuilder(
            JwtBearerDefaults.AuthenticationScheme)
                .RequireAuthenticatedUser()
                .RequireXafAuthentication()
                .Build();
    });
    // ...
    services.AddSwaggerGen(c => {
        c.EnableAnnotations();
        c.SwaggerDoc("v1", new OpenApiInfo {
            Title = "MySolution API",
            Version = "v1",
            Description = @"Use AddXafWebApi(Configuration, options) in the MySolution.WebApi\Startup.cs file to make Business Objects available in the Web API."
        });
        // The AddSecurityDefinition and AddSecurityRequirement methods enable the JWT authentication for the Swagger UI.
        c.AddSecurityDefinition("JWT", new OpenApiSecurityScheme() {
            Type = SecuritySchemeType.Http,
            Name = "Bearer",
            Scheme = "bearer",
            BearerFormat = "JWT",
            In = ParameterLocation.Header
        });
        c.AddSecurityRequirement(new OpenApiSecurityRequirement()
            {
                {
                    new OpenApiSecurityScheme() {
                        Reference = new OpenApiReference() {
                            Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
                            Id = "JWT"
                        }
                    },
                    new string[0]
                },
        });
    });

Step 4. Add a JWT Authentication Service

You can implement your own JWT service, or use the JWT service that the Solution Wizard generates. You can find the auto-generated service code below. To use this JWT service, create the JWT folder in the MySolution.WebApi (MySolution.Blazor.Server) project and add the AuthenticationController.cs file to this folder.

File: MySolution.WebApi\JWT\AuthenticationController.cs (MySolution.Blazor.Server\JWT\AuthenticationController.cs)

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Security.Authentication;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;

namespace MySolution.WebApi.JWT {
    [ApiController]
    [Route("api/[controller]")]
    public class AuthenticationController : ControllerBase {
        readonly IStandardAuthenticationService securityAuthenticationService;
        readonly IConfiguration configuration;

        public AuthenticationController(IStandardAuthenticationService securityAuthenticationService, IConfiguration configuration) {
            this.securityAuthenticationService = securityAuthenticationService;
            this.configuration = configuration;
        }
        [HttpPost("Authenticate")]
        public IActionResult Authenticate(
            [FromBody]
            [SwaggerRequestBody(@"For example: <br /> { ""userName"": ""Admin"", ""password"": """" }")]
            AuthenticationStandardLogonParameters logonParameters
        ) {
            ClaimsPrincipal user = securityAuthenticationService.Authenticate(logonParameters);

            if(user != null) {
                var issuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Authentication:Jwt:IssuerSigningKey"]));
                var token = new JwtSecurityToken(
                    issuer: configuration["Authentication:Jwt:Issuer"],
                    audience: configuration["Authentication:Jwt:Audience"],
                    claims: user.Claims,
                    expires: DateTime.Now.AddHours(2),
                    signingCredentials: new SigningCredentials(issuerSigningKey, SecurityAlgorithms.HmacSha256)
                    );
                return Ok(new JwtSecurityTokenHandler().WriteToken(token));
            }
            return Unauthorized("User name or password is incorrect.");
        }
    }
}

Step 5. Add the ApplicationUser and ApplicationUserLoginInfo Business Objects

XAF requires the ApplicationUser and ApplicationUserLoginInfo business objects to store user information. Add these business objects to the MySolution.Module project as described in the following topic: Use the Security System.

Use the Swagger UI to Test the JWT Authentication

1.If your solution includes a Web API project, right-click the project in the Solution Explorer and choose Debug | Start new instance to run the Web API project. A browser displays the page with the available endpoints.

If your solution includes a startup Blazor Server project with the Web API, run the application. Add /swagger to the application address (for example, https://localhost:44318/swagger ) and press Enter to display a page with available endpoints.

Refer to the following link for more information on the page’s UI: Swagger UI.

  1. Expand the Post Authentication endpoint and click the Try it out button.

  2. In the displayed form, enter the userName and password for an authorized user. In a template application, use Admin as the user name and an empty string as the password.

  3. Copy the public key from the Response body, click the Authorize button Authorize button to open the Available authorizations form, and paste the public key in the Value editor to enable the JWT authentication.

Configure JWT Authentication

Refer to the following topic for information on how to create Web API endpoints: Create Endpoints and Test the Web API.

See Also