Copied to clipboard

Flag this post as spam?

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


  • ianhoughton 233 posts 433 karma points c-trib
    Feb 27, 2018 @ 12:24
    ianhoughton
    0

    Extending backoffice login authentication

    We're using Umbraco 7.8.1 and trying to replace the backend user login, with our own authentication.

    So far I've created an UmbracoCustomOwinStartup.cs file and added this:

    app.ConfigureUserManagerForUmbracoBackOffice<BackOfficeUserManager, BackOfficeIdentityUser>(
                applicationContext,
                (options, context) =>
                {
                    var membershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider().AsUmbracoMembershipProvider();
                    var userManager = BackOfficeUserManager.Create(options, applicationContext.Services.UserService, applicationContext.Services.ExternalLoginService, membershipProvider);
    
                    //Set your own custom IBackOfficeUserPasswordChecker   
                    userManager.BackOfficeUserPasswordChecker = new MyPasswordChecker(context, userManager, membershipProvider.Name);
                    return userManager;
                });
    

    Note the replacement PasswordChecker which has this code:

    public async Task<BackOfficeUserPasswordCheckerResult> CheckPasswordAsync(BackOfficeIdentityUser user, string password)
        {
            string baseUri = ConfigurationManager.AppSettings["ApiBaseUri"];
    
            string tokenUri = string.Format("{0}/api/Token", baseUri);
    
            string clientId = "ElsieAdmin";
            var jwtProvider = JwtProvider.Create(tokenUri);
            string token = await jwtProvider.GetTokenAsync(user.UserName, password, clientId, Environment.MachineName);
            if (token == null)
            {
                return await Task.FromResult(BackOfficeUserPasswordCheckerResult.InvalidCredentials);
            }
            else
            {
                //decode payload
                dynamic payload = jwtProvider.DecodePayload(token);
                //create an Identity Claim
                ClaimsIdentity claims = jwtProvider.CreateIdentity(true, user.UserName, payload);
    
                // Grab the actual token value and add it to the claims identity
                dynamic jsontoken = JObject.Parse(token);
                claims.AddClaim(new Claim(ClaimTypes.Authentication, jsontoken.token.ToString()));
    
                // Add the environment details to the claims identity
                claims.AddClaim(new Claim(ClaimTypes.System, "website"));
                claims.AddClaim(new Claim(ClaimTypes.Uri, baseUri));
    
                // Add user details to the claims identity
                string userid = jsontoken.name;
                string username = jsontoken.userName;
                claims.AddClaim(new Claim(ClaimTypes.GivenName, userid));
                claims.AddClaim(new Claim(ClaimTypes.UserData, username));
    
                //sign in
                var userService = ApplicationContext.Current.Services.UserService;
                var existingUser = userService.GetByEmail(user.UserName);
                if (existingUser == null)
                {
                    var editorGroup = userService.GetUserGroupByAlias("editor");
                    existingUser = userService.CreateUserWithIdentity(user.UserName, user.UserName);
    
                    // need to add user to the Editor Group !!
                    // otherwise no sections are shown in backend
    
                    var identity = await _backOfficeUserManager.FindByEmailAsync(user.UserName);
                    identity.Name = userid;
                    await _backOfficeUserManager.UpdateAsync(identity);
                }
    
                var authenticationManager = _context.Authentication;
                authenticationManager.SignIn(claims);
    
                return await Task.FromResult(BackOfficeUserPasswordCheckerResult.ValidCredentials);
            }
    

    When the user attempts to log in and has a valid token from our auth server, we create a local user, but we have 2 problems:

    1) The first time they try to login, although we return ValidCredentials, umbraco is saying that login failed. If we then try to login again, the same code runs, but we are logged in to the backend.

    2) How do we add the new user to the Editors UserGroup? All code examples seem to be for the old obsolete way of doing it.

    existingUser.AddGroup(xxxxxx); is expecting a IReadOnlyGroup

  • ianhoughton 233 posts 433 karma points c-trib
    Mar 08, 2018 @ 08:59
    ianhoughton
    0

    I've sorted the adding the user to a group issue by adding these lines after:

    // need to add user to the Editor Group !!

    var ids = new List<int>();
    ids.Add(existingUser.Id);
    userService.Save(editorGroup, ids.ToArray(), true);
    

    Still have the issue of the backoffice user not being logged in straight after creating them.

  • David Emmett 4 posts 74 karma points
    May 09, 2018 @ 08:15
    David Emmett
    0

    I had a similar issue and fixed it by creating the user using BackOfficeUserManager instead of other methods.

    private BackOfficeUserManager<BackOfficeIdentityUser> _userManager;
    protected BackOfficeUserManager<BackOfficeIdentityUser> UserManager
    {
        get { return _userManager ?? (_userManager = HttpContext.Current.GetOwinContext().GetBackOfficeUserManager()); }
    }
    

    and then within CheckPasswordAsync:

    var userCreationResults = await UserManager.CreateAsync(user);
    if (userCreationResults.Succeeded)
    {
        //assign groups etc
    }
    

    An alternative way to add the goups is also:

    var userService = ApplicationContext.Current.Services.UserService;
    var newUser = userService.GetUserById(user.Id)
    var editorGroup = userService.GetUserGroupByAlias("editor") as IReadOnlyUserGroup;
    newUser.AddGroup(editorGroup);
    userService.Save(newUser);
    
Please Sign in or register to post replies

Write your reply to:

Draft