Copied to clipboard

Flag this post as spam?

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


  • Cornelis 9 posts 110 karma points
    Jul 29, 2020 @ 14:49
    Cornelis
    0

    How do I get user info during login, after the actual login but before calling SetAuthenticationSuccessful

    I am implementing 2FA for users in Umbraco 8 backoffice and I have the most of it working. But I got stuck at a point where I need user data but I cannot figure out how to get it.

    I need to know which user is logging in after he/she/it has entered the credentials and lands on the 2FA custom login page but before submitting a code on that page.

    The additional login 2FA page is shown via

    public string GetTwoFactorView(IOwinContext owinContext, UmbracoContext umbracoContext, string username) =>
            PackageConstants.PathToMfaHtmlTemplate;
    

    This template has an angularjs controller:

    <div ng-controller="mfaLoginController" class="umb-login-container">
      //...
    </div>
    

    and in the controller I got access to the services:

    userService
    authResource
    

    Unfortunately, both services doesn't seem to have the user data yet I need. It seems the user data is available after calling executing the verify2FACode:

            authResource.verify2FACode(providerName, quoted($scope.code)).then(
                data => {
                    userService.setAuthenticationSuccessful(data);
    
                    //Normally, this should be $scope.submit(true); 
                    //But this isn't working in umbraco 8, probably a bug?.
                    //For more info, check https://github.com/Dallas-msc/umbraco-2fa-with-google-authenticator/issues/1
                    $scope.$parent.vm.onLogin();
                },
                () => $scope.pinCodeMessage = pinCodInvalidMessage
            );
    

    The data in setAuthenticationSuccessful(data) seems to have the user info so this info is too late.

    Is there another service I could inject that actually got the information I need?

    Also, I need this information for some API calls I want to make. I figured out that a cookie is set after the login step 1, named

    .AspNet.UmbracoTwoFactorCookie

    And I can read the content of the cookie of course with

    var mfaCookie = Request.Headers.GetCookies(".AspNet.UmbracoTwoFactorCookie").FirstOrDefault()
                    .Cookies.FirstOrDefault(cookie => cookie.Name == ".AspNet.UmbracoTwoFactorCookie").Value;
    

    But this contains an encrypted OWIN string and I haven't succeeded yet in decrypting the string. Many decryptors I found uses the MachineKey decrypting but when I try to use those, it always ends up in the error:

    Error occurred during a cryptographic operation.

    Even when I put a machinekey in my web.config, I still get this error.

    Is there a way to get the user data (even when login is not successful yet because the user needs to enter a PIN-code) in the backend instead of retrieving it in the frontend perhaps?

    PS: I also opened a topic on stackoverflow as I am that eager to solve this issue.

  • Cornelis 9 posts 110 karma points
    Jul 30, 2020 @ 15:00
    Cornelis
    101

    I figured it out. By coincidence, while investigating a possible different solution for the problem I have, I stumbled on the AuthenticatorController of Umbraco (hooray for open source) and I saw this piece of code:

    private BackOfficeSignInManager _signInManager;
    
    private BackOfficeSignInManager SignInManager => _signInManager ?? (_signInManager = TryGetOwinContext().Result.GetBackOfficeSignInManager());
    

    Fortunately, I am able to use this code too in my controller and this line of code gave me what I need.

    var userId = await SignInManager.GetVerifiedUserIdAsync();
    
  • Simon Dingley 1435 posts 3338 karma points c-trib
    1 week ago
    Simon Dingley
    0

    Thanks for sharing this it has been really helpful in getting over a hurdle I was stuck on like you.

    In your API controller were you inheriting from UmbracoAuthorizedApiController or UmbracoApiController? My current problem is that I am using UmbracoAuthorizedApiController but understandably I get a 401 unauthorised error. I could make the verification endpoint public to get around this but it's not sitting right with me and I'm thinking I may need to come up with my authorisation attribute that makes use of the SignInManager in your example to at least check for the presence of the user id first.

Please Sign in or register to post replies

Write your reply to:

Draft