Hi
I have question is setting up the authentication / authorization in dynamic web is possiible in similar way as in .net ?
i am asking because basically i did it and it is working locally, but after deploy to stg env i cannot reach endpoints with attribute [Authorize] - i am getting 500
sample code :
[Authorize(Policy = AuthenticationConsts.Policy, AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpGet]
public ActionResult<bool> IsAuthorized()
{
_logger.Log($"IsAuthorized endpoint HIT. User.Identity.IsAuthenticated: {User?.Identity?.IsAuthenticated}, User.Identity.Name: {User?.Identity?.Name}");
_logger.Log($"User claims: {string.Join(", ", User?.Claims?.Select(c => $"{c.Type}={c.Value}") ?? Array.Empty<string>())}");
var isAuthenticated = User?.Identity?.IsAuthenticated ?? false;
return Ok(isAuthenticated);
}
pipeline
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
var jwtOptions = libConfig.GetSection(JwtOptions.SectionName).Get<JwtOptions>();
var loggerProvider = new Dynamicweb.Logging.LogToFile.LogToFileProvider();
var logger = loggerProvider.GetLogger("Pipeline.Logs", "Logs");
logger.Log($"Configuring JWT Bearer with options: " +
$"Issuer={jwtOptions?.Issuer}, " +
$"Audience={jwtOptions?.Audience}, " +
$"KeyLength={jwtOptions?.ClientSecretKey}");
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtOptions?.Issuer ?? string.Empty,
ValidAudience = jwtOptions?.Audience ?? string.Empty,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(jwtOptions?.ClientSecretKey ?? string.Empty)),
ClockSkew = TimeSpan.Zero,
RoleClaimType = ClaimTypes.Role
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
logger.Log($"Authentication failed: {context.Exception.GetType().Name} - {context.Exception.Message}");
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
logger.Log($"Token validated successfully. User: {context.Principal?.Identity?.Name}, IsAuthenticated: {context.Principal?.Identity?.IsAuthenticated}");
var roles = context.Principal?.FindAll(ClaimTypes.Role).Select(c => c.Value);
logger.Log($"User roles: {string.Join(", ", roles ?? Array.Empty<string>())}");
return Task.CompletedTask;
},
OnChallenge = context =>
{
logger.Log($"Authentication challenge: Error={context.Error}, ErrorDescription={context.ErrorDescription}, AuthFailure={context.AuthenticateFailure?.Message}");
return Task.CompletedTask;
},
OnMessageReceived = context =>
{
var token = context.Token;
logger.Log($"Token received: {(string.IsNullOrEmpty(token) ? "NULL/EMPTY" : $"Length={token.Length}")}");
return Task.CompletedTask;
}
};
});
services.AddAuthorization(options =>
{
options.AddPolicy(AuthenticationConsts.Policy, policy =>
{
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
policy.RequireRole(AuthenticationConsts.UserRole);
});
});
and RegisterApplicationComponents
public void RegisterApplicationComponents(IApplicationBuilder app)
{
var loggerProvider = new Dynamicweb.Logging.LogToFile.LogToFileProvider();
var logger = loggerProvider.GetLogger("Pipeline.Logs", "Logs");
app.Use(async (context, next) =>
{
var path = context.Request.Path.Value;
if (path?.StartsWith(ScanAppConsts.ApiPath, StringComparison.OrdinalIgnoreCase) == true)
{
logger.Log($"Request received: {context.Request.Method} {path}");
logger.Log($"Authorization header present: {context.Request.Headers.ContainsKey("Authorization")}");
}
await next();
});
app.MapWhen(IsCustomApiPath, app =>
{
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
});
static bool IsCustomApiPath(HttpContext context) => context.Request.Path.StartsWithSegments(ScanAppConsts.ApiPath, StringComparison.OrdinalIgnoreCase);
}
any ideas why this is working locally ? and not on env ? thanks in advance