Hi guys,
So firstly background, i have created a custom class library to represent another module im working on, it is MyModule.HttpApi for example, its added as a project reference to the main HttpApi project and it loads fine. It has custom middleware in it to serve files from a certain path (basically hiding the physical path to the file) so I can call https://localhost:44311/StaticFiles/image0.jpeg and it serves an image from where ever i want. This works fine too.
However now i am trying to protect it with authorization and im having real troubles. Obviously if you go straight to an image or file path there is no bearer token set on that request but cookies are sent. I can see when i look at dev console that cookies are in the request but i cant tell if they are the right cookies or not. So then i have read lots of docs and tried various things for it to recognise cookies but i cant tell if im doing it correctly.
Can you guys give me any info i should follow if i want cookies to work as well as bearer token?
I have tried lots of things with no luck and currently am sitting with the code below which also doesnt work. My custom policy only has context.Succeed in it so it should pass if it gets there but its blocked by the policy.RequireAuthenticatedUser(); I can tell its blocked cause if i remove that line then my handler gets picked up but debugging the context in that handler shows no claims either
.AddAuthentication(options =>
{
options.DefaultScheme = "IdentityAndCookie";// IdentityServerAuthenticationDefaults.AuthenticationScheme;
//options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
//options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddPolicyScheme("IdentityAndCookie", "Identity server and cookie", options =>
{
options.ForwardDefaultSelector = context =>
{
var bearerAuth = context.Request.Headers["Authorization"].FirstOrDefault()?.StartsWith("Bearer ") ?? false;
// You could also check for the actual path here if that's your requirement:
// eg: if (context.HttpContext.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCulture))
if (bearerAuth)
return IdentityServerAuthenticationDefaults.AuthenticationScheme;
else
return CookieAuthenticationDefaults.AuthenticationScheme;
};
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
//options.LoginPath = "/Account/Unauthorized/";
//options.AccessDeniedPath = "/Account/Forbidden/";
options.Cookie.Name = ".AspNetCore.Identity.Application";
})
.AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = true;
options.ApiName = "Hub";
})
;
context.Services.AddSingleton<IAuthorizationHandler, StaticFilesReadHandler>();
context.Services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme, IdentityServerAuthenticationDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
//.AddRequirements(new StaticFilesReadRequirement())
.Build();
options.AddPolicy("StaticFiles.Read", policy =>
{
policy.AuthenticationSchemes.Add(CookieAuthenticationDefaults.AuthenticationScheme);
//policy.AuthenticationSchemes.Add(IdentityServerAuthenticationDefaults.AuthenticationScheme);
policy.RequireAuthenticatedUser();
policy.Requirements.Add(new StaticFilesReadRequirement());
});
});
@arifharsono I believe you have to create it in the Host/Web/Identity projects (depending on what setup your using) to get access to DefaultBrandingProvider
Its located in Volo.Abp.AspNetCore.Mvc.UI.Theme.SharedComponents
Sorry question 3
If the incoming roles are coming in with claim name 'group' is there a configuration option i can use to automatically map that to 'role'? I have tried a heap of different config combinations but im not sure if they should work or not based on the 2 questions above
Hi guys,
Two questions:
Regards, Pete
@Mehmet thanks did not realise i could replace whole account component, although i dont know if i still need forgot password and other pages other than login so i will try authguard injection first!
@gterdem ok great i will try reproduce in new solution and then log an issue if thats the case
Thanks again for all the help
@gterdem hi
What would be the best practise then to catch all the exceptions so I can wrap the relevant ones into User Friendly ones such as the password format when registering being incorrect. e.g if a user registers a new account with password of 'a' then thats invalid and they just get a blank screen on hitting register rather than a validation error.
@alper thanks I will get a new solution and just confirm it is indeed reproducible and will log a bug if it is. I will also try a combined solution and see if its any different
@yekalkan
Ok cool!
So now my last 2 questions really
Thanks again
Hi @alper
After further investigation I can see the properties for both PKCE and RequireClientSecrets in the src code for the ABP identityserver domain object as well as the ETO object.
https://github.com/abpframework/abp/tree/dev/modules/identityserver
but i dont have the license to the UI modules to see if they are in there, maybe you can confirm? To reiterate I am simply wondering if the options exist and I cant find them or if they have not been added to the UI yet?
hi @alper
This documentation found at this link shows a screenshot with PKCE option, i will keep looking for RequireClientSecret
Im not sure how this helps unless ABP IO is built on top of that UI? Im happy to try and add the UI for it to ABP IO if it doesnt exist I am simply wondering if it is on a screen I have missed
hi @alper
No I didnt set them using the official admin UI, i did it direct in the database. I have not looked at the official UI only the ABP IO implementation?
I will have a look at the official implementation and see if i can find them