Did you get anywhere with this? I am trying to check if a back office user is currently logged in to the back office in a INotificationHandler<RoutingRequestNotification>, however this code always returns null:
var user = _backOfficeSecurityAccessor.Value.BackOfficeSecurity.CurrentUser;
Do you mean from one of the public websites razor views, you want to know if the person viewing the page is currently a backoffice user logged into the backoffice?
If so, you might need to authorize the request using the backoffice authentication scheme. This doesn't happen out-of-the box, I don't think.
Shooting from the hip here, but maybe something like this will work?
Override the default rendering controller, so you can decorate it with the authorize attribute:
.
[Authorize(AuthenticationSchemes = Umbraco.Cms.Core.Constants.Security.BackOfficeAuthenticationType)]
[AllowAnonymous]
public class CustomRenderController : RenderController
{
public CustomRenderController(ILogger<RenderController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor)
: base(logger, compositeViewEngine, umbracoContextAccessor)
{
}
}
Edit: I took this from Umbracos own preview code...
Well, here's what I ended up doing in my Middleware:
private void AddBackofficeIdentityIfAvailable(HttpContext context)
{
var cookieOptions = context.RequestServices.GetRequiredService<IOptionsSnapshot<CookieAuthenticationOptions>>()
.Get(Umbraco.Cms.Core.Constants.Security.BackOfficeAuthenticationType);
if (cookieOptions == null)
{
throw new InvalidOperationException("No cookie options found with name " + Umbraco.Cms.Core.Constants.Security.BackOfficeAuthenticationType);
}
if (context.Request.Cookies.TryGetValue(cookieOptions.Cookie.Name, out var cookie))
{
var unprotected = cookieOptions.TicketDataFormat.Unprotect(cookie);
var backOfficeIdentity = unprotected?.Principal.GetUmbracoIdentity();
if (backOfficeIdentity != null)
{
// Ok, we've got a real ticket, now we can add this ticket's identity to the current
// Principal, this means we'll have 2 identities assigned to the principal which we can
// use to authorize and allow for a back office User.
context.User.AddIdentity(backOfficeIdentity);
}
}
}
Then I tried getting the backOfficeIdentity liks this:
var backOfficeIdentity = context.User.Identities.FirstOrDefault(c => c.AuthenticationType == Umbraco.Cms.Core.Constants.Security.BackOfficeAuthenticationType);
And finally you can check if it's ok and authenticated with
Hey Warren, I am trying to determine if a backoffice user is logged in and possibly what groups the user belongs to outside of backoffice routed requests.
It does look like your recent code examples provide the required information, thank you MatsStam and Warren for taking the time.
If the value in the authentication cookie is very large then it's automatically split up into chunks and split over multiple cookies. This was the situation in my case, so I tweaked the code ever so slightly by using ChunkingCookieManager (nom nom) to get it to work:
public ClaimsIdentity BackOfficeUser
{
get
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null)
return new ClaimsIdentity();
var cookieOptions = _cookieOptionsSnapshot.Get(Umbraco.Cms.Core.Constants.Security.BackOfficeAuthenticationType);
var cookieManager = new ChunkingCookieManager();
var backOfficeCookie = cookieManager.GetRequestCookie(httpContext, cookieOptions.Cookie.Name!);
if (string.IsNullOrEmpty(backOfficeCookie))
return new ClaimsIdentity();
var unprotected = cookieOptions.TicketDataFormat.Unprotect(backOfficeCookie!);
var backOfficeIdentity = unprotected!.Principal.GetUmbracoIdentity();
return backOfficeIdentity ?? new ClaimsIdentity();
}
}
Hope that helps somebody else in a similar situation.
Hi Marcus, thank you so much for sharing your solution. I cannot make it work in Razor-view.
Can you advice me how to check (in Razor) if the user is logged in to Backoffice, when using your "IBackofficeUserAccessor"-implementation?
I am trying something like this:
var LoggedIn = new BackofficeUserAccessor().BackofficeUser;
This way I have checked in Umbraco 8 earlier:
var ticket = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current).GetUmbracoAuthTicket();
Hi Mats and Paul, Thank you so much for your answers and effort. I will try and see if I can make it work.
Mats:
I tried injecting it into the razor-view but I get the error:
InvalidOperationException: No service for type 'Umbraco9Test5.IBackofficeUserAccessor' has been registered.
Paul:
I have exactly the described need: To show an "Edit-icon", if the user is logged in, that links directly to the backoffice-node so administrators quickly can go the the backoffice-page and change the content.
I will try out the tag-helper-method and see if I can make it work.
I used Markus’ code to enable me to create a tag helper which renders an edit link on the front end of the user is logged into Umbraco.
Our next move is to create a tag helper for only showing content if the user is logged into Umbraco. I think it will probably be added this week or next.
It will probably work like this:
blah
If the user is not logged into Umbraco then the div and its contents won’t be rendered.
Paul :) I tried to work with the Taghelper and got it to work. In my case I think it is a little overkill to use a taghelper for checking this, when you can use a simple if-statement. Once again I really appreciate your feedback. Feel free to contact me if you need more info...
hello - Ive just come across this thread and like Peter Dyhrberg i am looking for a way of determing if there is currently a backoffice user logged in so that on the website frontend a convenient edit link can be provided to the respective content in the CMS. Is this still a case of rolling your own or is there something in 9.2 or forthcoming in 9.3 that helps with this? thanks
How do i determine 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.
IBackOfficeSecurityAccessor BackofficeSecurityAccessor doesn't seem to help
Seems pretty impossible right now?
Hi Gunnar,
Did you get anywhere with this? I am trying to check if a back office user is currently logged in to the back office in a
INotificationHandler<RoutingRequestNotification>
, however this code always returns null:CurrentUser is always null.
I've got the same problem using the IBackOfficeSecurity:
CurrentUser is always null...
Do you mean from one of the public websites razor views, you want to know if the person viewing the page is currently a backoffice user logged into the backoffice?
If so, you might need to authorize the request using the backoffice authentication scheme. This doesn't happen out-of-the box, I don't think.
Shooting from the hip here, but maybe something like this will work?
.
register it in startup.cs:
This will try authorize the request with the backoffice scheme, but because we have "AllowAnonymous" it wont force the user to login.
In the razor view, you can use:
Hmm. This might only be able to work if you are not also using member login.
Hi Gunnar 👋
I am curious as to what you are trying to achieve by wanting the logged in back office to be available on the front end of the site.
As with anything in code depending on what your trying to do, there may be one or more ways to how to solve the problem.
Warren
Edit: I took this from Umbracos own preview code...
Well, here's what I ended up doing in my Middleware:
Then I tried getting the backOfficeIdentity liks this:
And finally you can check if it's ok and authenticated with
OK I got a reply internally as was suggested a similar code sample as MatsStam, that might also help you.
Hey Warren, I am trying to determine if a backoffice user is logged in and possibly what groups the user belongs to outside of backoffice routed requests.
It does look like your recent code examples provide the required information, thank you MatsStam and Warren for taking the time.
Thanks everyone for sharing your progress! Code samples works like a charm!
I figured I'll share my "IBackofficeUserAccessor"-implementation.
Feel free to use this in your own projects, both closed and open source. I give my full permissions.
Thanks for this Markus. Is it ok if I borrow some/all of this to update my edit link package from v8 to v9 please?
Just do it! =D
Thanks - found this really useful.
If the value in the authentication cookie is very large then it's automatically split up into chunks and split over multiple cookies. This was the situation in my case, so I tweaked the code ever so slightly by using ChunkingCookieManager (nom nom) to get it to work:
Hope that helps somebody else in a similar situation.
Hi Sean,
Just wanted you to know that I have bumped into this exact same issue and your solution works a treat. Thanks for sharing #h5yr
Here again - thanks Markus - we need this merged in IMHO :)
Will mark as answered to help others despite not having had a chance to test myself, thanks all
Hi Marcus, thank you so much for sharing your solution. I cannot make it work in Razor-view. Can you advice me how to check (in Razor) if the user is logged in to Backoffice, when using your "IBackofficeUserAccessor"-implementation?
I am trying something like this: var LoggedIn = new BackofficeUserAccessor().BackofficeUser;
This way I have checked in Umbraco 8 earlier: var ticket = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current).GetUmbracoAuthTicket();
Thanks again Marcus. /Best regards Peter
Maybe try injecting it into your razor view?
Haven't tried it since I'm using my implementation in my Middleware :P But that should make you able to do:
Hi Mats and Paul, Thank you so much for your answers and effort. I will try and see if I can make it work.
Mats: I tried injecting it into the razor-view but I get the error:
InvalidOperationException: No service for type 'Umbraco9Test5.IBackofficeUserAccessor' has been registered.
Paul: I have exactly the described need: To show an "Edit-icon", if the user is logged in, that links directly to the backoffice-node so administrators quickly can go the the backoffice-page and change the content. I will try out the tag-helper-method and see if I can make it work.
/ Best regards Peter
Ah, you need to register it in your startup.cs too :) Otherwise the DI won't work :)
Something like:
I'm all new to .Net 5 myself, so maybe you don't want to register it as a Transient, but singelton or whatever, depending on your need :)
Hi There is a community package called Our.Umbraco.TagHelpers.
https://www.nuget.org/packages/Our.Umbraco.TagHelpers/
I used Markus’ code to enable me to create a tag helper which renders an edit link on the front end of the user is logged into Umbraco.
Our next move is to create a tag helper for only showing content if the user is logged into Umbraco. I think it will probably be added this week or next.
It will probably work like this:
blah
If the user is not logged into Umbraco then the div and its contents won’t be rendered.
Paul
Great stuff!
Hi Mats, Thanks a lot. It worked. Here is my solution:
make a new class file in the root of your project and name it "BackofficeUserAccessor.cs" and copy Marcus code suggestion into the file (see above)
open your startup.cs file and insert the following into the ConfigureServices method:
open your Razor-view / cshtml-file
@inject IBackofficeUserAccessor _backofficeUserAccessor
var IsAdmin = _backofficeUserAccessor.BackofficeUser.IsAuthenticated;
Paul :) I tried to work with the Taghelper and got it to work. In my case I think it is a little overkill to use a taghelper for checking this, when you can use a simple if-statement. Once again I really appreciate your feedback. Feel free to contact me if you need more info...
Here is the example with the tag-helper:
Best regards Peter
Hi Peter
It's interesting that you say using a tag helper is overkill. It keeps all of the code out of the view.
For anyone else interested in this package. Here's how you use it:
Then update your
/Views/_ViewImports.cshtml
file to use this tag helpers packageThe package does all the registering of the service for you, then it is very simple to use it:
Which outputs the link like this:
N.B. The edit link tag helper checks if the user is logged into the backoffice and if they have access to the content section before showing the link.
Kind regards
Paul
hello - Ive just come across this thread and like Peter Dyhrberg i am looking for a way of determing if there is currently a backoffice user logged in so that on the website frontend a convenient edit link can be provided to the respective content in the CMS. Is this still a case of rolling your own or is there something in 9.2 or forthcoming in 9.3 that helps with this? thanks
is working on a reply...