Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Aaron Shelby 5 posts 75 karma points
    Sep 09, 2021 @ 21:37
    Aaron Shelby
    0

    Umbraco Page Public Access Blocking Valid Members

    I'm running into a problem with setting the public access of a subpage. I started by creating an HRAdmin group and assigning my member account to it. I then set group based protection on a page of the site, set the group to HRAdmin, set the login page to "home" (since logging in is handled by a custom controller - I'll cover that in a minute), and set the error page to a custom error page that spits out the current user's info. Here's the cshtml snippet of the data I'm listing.

    <H1>User Info</H1>
    
    <p>Logged in? @Members.IsLoggedIn()</p>
    <P>Logged in as @Members.CurrentUserName (@Members.GetCurrentMemberId())</P>
    <p>
        Part of the following membership groups: <br>
        @foreach (var role in Members.GetCurrentUserRoles()){
            <span>@role</span><br>
        }
    </p>
    

    When I attempt to view the protected page, I am shown the user info of the custom error page, which shows True for Member.IsLoggedIn(), shows my username for Members.CurrentUserName and shows a valid ID for Members.GetCurrentMemberId - which pulls up my user account when I search for that ID in the backoffice. And it list HRAdmin in the list of roles.

    So I tried changing the public access to specific members protection and selected my member account. That doesn't work either, and I get the same custom error page with the same user info.

    I don't think the custom controller automatic login has anything to do with it but just in case, here's what I'm doing. This is an intranet site, and we have IIS set up for Windows Authentication only. The custom controller figures out the Windows user accessing the site, gets that user's email address (through Active Directory) and attempts to log in to Umbraco membership with that email address. If they don't exist, the controller creates the member first.

    I have a custom composer implementing IUserComposer that calls composition.SetDefaultRenderMvcController with my custom controller. The controller code is as follows.

        public override ActionResult Index(ContentModel model)
        {
            if (Members.GetCurrentMemberId() == -1) 
                LogInUmbracoUser();
    
            Members.IsMemberAuthorized();
            //do whatever Umbraco would have done wihtout this custom controller
            return base.Index(model);
        }
    
    
        private void LogInUmbracoUser()
        {
            var AD = new Library.ActiveDirectory.Connection(_adcServer);
            var AdUser = AD.GetUser(HttpContext.ApplicationInstance.Context); 
    
            //find the umbraco member for that user
            var UmbracoMember = Members.GetByEmail(AdUser.Email);
    
            //if they're a new member, add them
            if (UmbracoMember == null)
                AddUmbracoUser(AdUser, _DefaultPassword);
    
            //log them in, new or not
            Members.Login(AdUser.Email, _DefaultPassword);
    
            //set the httpcontext with the user information so that the user shows up in the view on the first page load. 
            //Without this line, the user is logged in but the first page they visit (the one initiating the login check) won't treat them as logged in.
            SetCurrentUser();
        }
    
        private void AddUmbracoUser(Library.ActiveDirectory.User AdUser, string Password)
        {
            RegisterModel UmbracoMember = RegisterModel.CreateModel();
            UmbracoMember.Email = AdUser.Email;
            UmbracoMember.Name = AdUser.FullName;
            UmbracoMember.UsernameIsEmail = true;
            UmbracoMember.Password = Password;
    
            Members.RegisterMember(UmbracoMember, out _, logMemberIn: false);
        }
    
        private void SetCurrentUser()
        {
            var cookie = Response.Cookies[FormsAuthentication.FormsCookieName];
            if (cookie != null)
            {
                var ticket = FormsAuthentication.Decrypt(cookie.Value);
                if (ticket != null && !ticket.Expired)
                {
                    var roles = (ticket.UserData as string ?? "").Split(',').ToList();
                    HttpContext.User = new ClaimsPrincipal(new GenericPrincipal(new FormsIdentity(ticket), roles.ToArray()));
                }
            }
        }
    
Please Sign in or register to post replies

Write your reply to:

Draft