I am trying to create an AuthorizationFilter filter in Umbraco 9.
public bool Authorize([NotNull] DashboardContext context)
{
var httpContext = context.GetHttpContext();
var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
bool success = authService.AuthorizeAsync(httpContext.User, this.policyName).ConfigureAwait(false).GetAwaiter().GetResult().Succeeded;
return success;
}
The trouble is the user from the context is always null regardless to if I am logged in to Umbraco or not.
I am trying to port this code over from Umbraco 8.
public bool Authorize(DashboardContext context)
{
var http = new HttpContextWrapper(HttpContext.Current);
var ticket = http.GetUmbracoAuthTicket();
http.AuthenticateCurrentRequest(ticket, true);
var user = Current.UmbracoContext.Security.CurrentUser;
return user != null && user.Groups.Any(g => g.Alias == "admin");
}
Any ideas - I am guessing I am missing something valuable from the startup.cs.
It looks like the user isn't in context at that stage.
This might not be as easy as first though.
I think I will get hangfire working without this. I have managed to get it working with authorization disabled. I also got it working using a username and password.
I just wanted to go one step further and get this working only for logged in users.
Getting up and running with Hangfire for Umbraco 9.
I am fully up and running with Hangfire but there is this last issue (related to this task) preventing me from security the Hangfire dashboard based on if the Umbraco user is logged in or not.
I'll relay Shannon's answer to me about this, we haven't figured this out together yet:
I'll try to explain - this is Authentication (AuthN) vs Authorization (AuthZ)
In Umbraco, there are specific request paths that are authenticated for the back office and the rest are authenticated as the front-end. This is how it is possible to have both Members and Users working at the same time. Some paths are considered back office and as such, we will execute the AuthN process for the back office (i.e. cookie authentication for the back office). If the AuthN succeeds the User (Principal) is assigned to the HttpContext. If the request is not for the back office, it will run the AuthN for the front (i.e. cookie authentication for the front-end members).If the AuthN succeeds the User (Principal) is assigned to the HttpContext.
How a back office request is determined is based on one method UmbracoRequestPaths.IsBackOfficeRequest (in v8 this is a little different).
In both v8 and v9, we need a way to register a non-standard back office request as a back office request. Alternatively, things that need to be Authenticated as a back office request, should be routed as such.
You can change the route to be a back office route. Most things in /umbraco/* are considered as such. There are a few exceptions like surface controllers and api controllers that are front-end controllers but are also routed under the /umbraco route (which is why we have the [IsBackOffice] attribute. You can have a look at the IsBackOfficeRequest method and tests to see what is a back office request.
I tried simply updating the /hangfire route to /umbraco/hangfire but no luck with that. Something "extra" needs to happen and I didn't have the time to work on that yet.
Just found a way to restrict access to Hangfire for Members or to Backoffice Users
To restrict access to Umbraco BackOffice Users, it only works if the hangfire url starts with /umbraco/backoffice/. Did not find a way to make it works with only /hangfire
For BackOffice Users access I used the BackOfficeAccess Authorization policy provided by Umbraco but you could also define your own policy to add multiple criterias ;-)
@Marc yeah looks like we can't secure arbitrary routes they need to be in the /umbraco route (whatever your route is for the backoffice.. and I just remembered that I shouldn't hardcode that, since the route is configurable).
Please do note that Grégory's code opens the dashboard up to anyone with backoffice access, I am specifically limiting it to backoffice users with access to the Settings section of Umbraco.
endpoints.MapHangfireDashboard(pattern: "/umbraco/backoffice/hangfire",options: new DashboardOptions()).RequireAuthorization(Constants.System.HangfireDashboard);
Note: this is not checking for any user rights, you have to tweak it yourself.
‼️
Make sure to do tweak this! Or just use my package, which has a proper check in place, which I'd encourage everyone to use in their custom code if they need it. This ensures people can only access the hangfire route if they have access to the Settings section of Umbraco.
If I recall correctly, I tried something similar to the code above sort of worked for me but wasn't reliable (sorry can't remember why).
Thanks Sebastiaan, I am using the dashboard part, works pretty cool within the Umbraco BO. 👍
However, in order to access the Hangfire tab , the user should have rights to the settings section as well, is this tweakable (f.e role specific)? In some rare cases we don't want certain users to access the settings section.
Maybe in this case my previous post can be handy, I edited the post and added some role checks.
As I said, I have doubts your code is fully secure.
You can't tweak it with my package yet but in the code I linked to you could change AuthorizationPolicies.SectionAccessSettings to "MySection" - in case you put it in a custom section, or one of the default sections:
Umbraco 9 AuthorizationFilter - User Always Null
Hi All,
I am trying to create an AuthorizationFilter filter in Umbraco 9.
The trouble is the user from the context is always null regardless to if I am logged in to Umbraco or not.
I am trying to port this code over from Umbraco 8.
Any ideas - I am guessing I am missing something valuable from the startup.cs.
Thanks in Advance
Regards
David
HI David.
You should try
This should give you the Umbraco user instead of a member. I THINK. Not 100% sure :)
Unfortunately that didn't work.
It looks like the user isn't in context at that stage. This might not be as easy as first though.
I think I will get hangfire working without this. I have managed to get it working with authorization disabled. I also got it working using a username and password.
I just wanted to go one step further and get this working only for logged in users.
Maybe I will revisit this at a later date.
Just adding a bit of context here.
This is relating to this article I wrote.
https://www.umbrajobs.com/blog/posts/2021/june/umbraco-9-configuring-hangfire-scheduled-tasks/
Getting up and running with Hangfire for Umbraco 9.
I am fully up and running with Hangfire but there is this last issue (related to this task) preventing me from security the Hangfire dashboard based on if the Umbraco user is logged in or not.
Kind Regards
David
Hi David
Just guessing from the code, but have you tried injecting BackofficeSecurityAccessor?
I saw this PR here: https://github.com/umbraco/Umbraco-CMS/pull/8871/files
and on another PR about removing UmbracoBackofficeIdentity
https://github.com/umbraco/Umbraco-CMS/pull/9833#issuecomment-783593383
there is the suggestion of
(after injecting the BackOfficeSecurityAccessor)
being the new way to access the current backoffice user, but I haven't tried it!
regards
marc
I'll relay Shannon's answer to me about this, we haven't figured this out together yet:
I tried simply updating the
/hangfire
route to/umbraco/hangfire
but no luck with that. Something "extra" needs to happen and I didn't have the time to work on that yet.Hi Seb
Did you try routing via
/umbraco/backoffice/hangfire
???
I think it's anything routed via /umbraco/backoffice that is denoted as a backoffice request...
regards
marc
Ah, great suggestion, but no luck! My InPrivate window does not ask for any auth! 😅
Still working on this. I need to figure out how to compose this without injecting it in to see if that will work.
Anyone any ideas how to compose something without dependency injection using Umbraco 9?
Like we used to do for 8 inside custom classes or razor views.
Is there any update on how this could work?
Possibly related issue is determining if a backoffice user is logged in from a razor view.
User.GetUmbracoIdentity() is always null probably since we haven't Authenticated.
AuthenticationService.AuthenticateAsync doesn't work since the cookie manager stops the flow if it's not a backoffice route.
Seems pretty impossible right now
Hi,
Just found a way to restrict access to Hangfire for Members or to Backoffice Users
To restrict access to Umbraco BackOffice Users, it only works if the hangfire url starts with /umbraco/backoffice/. Did not find a way to make it works with only /hangfire
Here are the gists
Umbraco9 & Hangfire with Member access https://gist.github.com/An0d/46d2e5d5fab229f744669c4676adc07b
Umbraco9 & Hangfire with BackOffice User access https://gist.github.com/An0d/497766f14b452b278c8f4dfa3ac74c16
For BackOffice Users access I used the BackOfficeAccess Authorization policy provided by Umbraco but you could also define your own policy to add multiple criterias ;-)
Hope it helps
Think you've found the same thing I did! 👍
https://cultiv.nl/blog/setting-up-hangfire-in-umbraco-9/
It's also an Umbraco package now so no need to write the plumbing code: https://our.umbraco.com/packages/developer-tools/cultivhangfire/
Ah, I didn't notice the member access, that could be useful for some!
ooh, So my hunch was right?
@Marc yeah looks like we can't secure arbitrary routes they need to be in the
/umbraco
route (whatever your route is for the backoffice.. and I just remembered that I shouldn't hardcode that, since the route is configurable).Please do note that Grégory's code opens the dashboard up to anyone with backoffice access, I am specifically limiting it to backoffice users with access to the
Settings
section of Umbraco.This is great. Only thing missing is changing:
To:
Else it does not work on a remote environment. But thank you guys for doing the heavy lifting!
I think I found a way for David's initial issue, the Authorize method like in the old times, Umbraco 8.
I use this solution to get the current BO user. https://our.umbraco.com/forum/umbraco-9/106857-how-do-i-determine-if-a-backoffice-user-is-logged-in-from-a-razor-view#comment-334423
Then apply this in the Authorize dashboard authorization.
Note: this is not checking for any user rights, you have to tweak it yourself.
Edit; here is the BackofficeUserAccessor code including role stuff
And you'll have the role check available for the filter
‼️
Make sure to do tweak this! Or just use my package, which has a proper check in place, which I'd encourage everyone to use in their custom code if they need it. This ensures people can only access the hangfire route if they have access to the Settings section of Umbraco.
If I recall correctly, I tried something similar to the code above sort of worked for me but wasn't reliable (sorry can't remember why).
Oh forgot the link: https://github.com/nul800sebastiaan/Cultiv.Hangfire/blob/main/Cultiv.Hangfire/HangfireComposer.cs#L53
And the package with readme: https://our.umbraco.com/packages/developer-tools/cultivhangfire/
I'll keep this up-to-date, I need it myself.
Thanks Sebastiaan, I am using the dashboard part, works pretty cool within the Umbraco BO. 👍
However, in order to access the Hangfire tab , the user should have rights to the settings section as well, is this tweakable (f.e role specific)? In some rare cases we don't want certain users to access the settings section.
Maybe in this case my previous post can be handy, I edited the post and added some role checks.
What still plays a role is your findings regarding reliability, did you mean the IBackofficeUserAccessor or just the IDashboardAuthorizationFilter part? Also because of the earlier referenced topic https://our.umbraco.com/forum/umbraco-9/106857-how-do-i-determine-if-a-backoffice-user-is-logged-in-from-a-razor-view
As I said, I have doubts your code is fully secure.
You can't tweak it with my package yet but in the code I linked to you could change
AuthorizationPolicies.SectionAccessSettings
to"MySection"
- in case you put it in a custom section, or one of the default sections:I will need to investigate role-based access again, but that's for the future.
is working on a reply...