Dear Team,
I am using Identity Core with SS Ver 8.2.2 and trying to secure an endpoint below is the code of Apphost(s), program.cs and other relevant code FYR
public class AppHost : AppHostBase, IHostingStartup
{
public AppHost() : base("Ecomm.Consumer", typeof(Ecomm.Consumer.ServiceInterface.MyServices).Assembly)
{
}
public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices(services => {
// Configure ASP.NET Core IOC Dependencies
})
.ConfigureAppHost(appHost =>
{
});
public override void Configure()
{
// Configure ServiceStack, Run custom logic after ASP.NET Core Startup
SetConfig(new HostConfig
{
DebugMode = false,
});
}
ConfigureAuth.cs
public class ConfigureAuth : IHostingStartup
{
public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices((context, services) =>
{
services.AddPlugin(new AuthFeature(IdentityAuth.For<ApplicationUser>(options => {
options.CredentialsAuth();
options.SessionFactory = () => new CustomUserSession();
options.IncludeRegisterService = true;
options.AdminUsersFeature();
})));
});
}
public class CustomUserSession : AuthUserSession
{
public override void PopulateFromClaims(IRequest httpReq, ClaimsPrincipal principal)
{
DisplayName = principal.FindFirstValue(JwtClaimTypes.NickName);
}
}
public class AdditionalUserClaimsPrincipalFactory(
UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>(userManager, roleManager, optionsAccessor)
{
public override async Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
{
var principal = await base.CreateAsync(user);
var identity = (ClaimsIdentity)principal.Identity!;
var claims = new List<Claim>();
if (user.DisplayName != null)
claims.Add(new Claim(JwtClaimTypes.NickName, user.DisplayName));
identity.AddClaims(claims);
return principal;
}
}
Request/ResponseDTO
[Route("/hello/{Name}")]
[Authorize(Roles ="Customer")]
public class Hello : IGet, IReturn<HelloResponse>
{
public string? Name { get; set; }
}
public class HelloResponse
{
public string? Result { get; set; }
}
Service
public class MyServices : Service
{
public object Get(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
When I try to call the API at this location https://localhost:5001/hello/name using the freshly generated token then I am able to successfully land into the GET method mentioned above. However, when the token is expired I am receiving 404 Not Found error, rather I am expecting 401 UnAuthorized.
If possible please advise the right way to deal this issue
Update
I was trying to investigate further and noticed that when I am providing a valid token then the response headers are different and when it is saying 404 Not Found then the response headers are different. Below screenshots are FYR. Can I say that may be when the token is expired the request is not reaching to servicestack at all? Just my 2 cents
Successful Response
Failed Response
Regards,