Copied to clipboard

Flag this post as spam?

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


  • Adam Zimmer 5 posts 85 karma points
    Feb 11, 2016 @ 15:23
    Adam Zimmer
    0

    Link External User Programmatically

    Hello, I was wondering if there was a way to link external users to a user through code. For example if I want to link a google account and want to link it to an existing user, can I do this programmatically?

    after looking at the database it looks like I somehow need to insert a record into the dbo.UmbracoExternalUser table. Is this possible through the API?

    Thanks in advance for your help.

  • Shannon Deminick 1526 posts 5272 karma points MVP 3x
    Feb 11, 2016 @ 20:40
    Shannon Deminick
    0

    We have this class to auto-link external accounts with using OAuth: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/Security/Identity/ExternalSignInAutoLinkOptions.cs

    There's more issue on this issue: http://issues.umbraco.org/issue/U4-6753

    We need to add all of this stuff to documentation. Hope this is what you are after, but of course auto-linking public Google accounts is not really a good idea because then anyone would have access to your back office that has a Google account. If they are your organization google accounts that should work for you.

  • Adam Zimmer 5 posts 85 karma points
    Feb 11, 2016 @ 20:53
    Adam Zimmer
    0

    Thanks for the reply Shannon, this is close to what I want I should have been more specific though. I am creating a back office user in code:

     var userService = ApplicationContext.Current.Services.UserService;
            var userTypes = userService.GetAllUserTypes();
    
            var theNewUser = userService.CreateUserWithIdentity("testuer", "[email protected]", userTypes.FirstOrDefault());
    

    and want to do something like this with the new user in the same function:

    theNewUser.LINKGOOGLEACCOUNT("email", "provider");
    

    Is there something like this in the existing API? Thanks a lot.

  • Shannon Deminick 1526 posts 5272 karma points MVP 3x
    Feb 12, 2016 @ 09:22
    Shannon Deminick
    100

    Oh right i see what you mean, yes there is an API for that which is just part of the ASP.Net Identity APIs, you can see it's usage here: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/Editors/BackOfficeController.cs#L449

    It is the Identity UserManager.AddLoginAsync method where the UserManager is Umbraco's BackOfficeUserManager which you can get from the OWIN context, for example: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/Editors/BackOfficeController.cs#L57

  • Dan White 206 posts 510 karma points c-trib
    Sep 27, 2016 @ 23:55
    Dan White
    0

    Adam:

    Did you ever figure out how to do this? I'm currently trying to do the same and not having much luck.

    Thanks!

  • Adam Zimmer 5 posts 85 karma points
    Sep 28, 2016 @ 14:26
    Adam Zimmer
    0

    Hey Dan, I did get this to work but its been awhile. I managed to dig up some code that hopefully will help you out. This might not be everything but it should get you started on the right path.

    In your web config configure your providers:

    <membership defaultProvider="PorchlightMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <clear />
        <add name="MyMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="MyConnectionString" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="50" minRequiredPasswordLength="8" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
        <add name="UmbracoMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="MyConnectionString" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="50" minRequiredPasswordLength="8" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />        
        <add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="8" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
      </providers>
    </membership>
    

    Add these 4 files from my github - https://github.com/Vepar/UmbracoBackOfficeConfiguration to your App_Start folder to configure Auth Tokens, Custom Owin Startups, Umbraco Google Auth, etc. (you may also need to download the necessary nuget packages).

    This should get you off to a good start. Let me know if you are still running in to issues.

    -Adam

  • Dan White 206 posts 510 karma points c-trib
    Sep 28, 2016 @ 18:46
    Dan White
    0

    Thanks, Adam. I was able to get the Google Auth working, but now I'm trying to figure out how to programmatically link a Google account with an Umbraco user. Much like you mention above with

    theNewUser.LINKGOOGLEACCOUNT("email", "provider");
    

    Thanks again

  • Dan White 206 posts 510 karma points c-trib
    Sep 28, 2016 @ 23:42
    Dan White
    0

    Here's what I just got working. I don't know if I'm going about it the right way or if I'm doing it in the right location, but it seems to be working.

    Basically, a Google user gets authenticated. When that happens I...

    • Make sure their email contains a valid domain
    • Look for an existing user with the email
    • Check to see if the accounts are already linked.
    • If not, link them

    Ideally, I would link them when I create the user, but it's not possible to link an account without actually making the OAuth request, right?

        public static void ConfigureBackOfficeGoogleAuth(this IAppBuilder app, string clientId, string clientSecret,
            string caption = "Google", string style = "btn-google-plus", string icon = "fa-google-plus")
        {
            var googleOptions = new GoogleOAuth2AuthenticationOptions
            {
                ClientId = clientId,
                ClientSecret = clientSecret, 
                //In order to allow using different google providers on the front-end vs the back office,
                // these settings are very important to make them distinguished from one another.
                SignInAsAuthenticationType = Constants.Security.BackOfficeExternalAuthenticationType,
                //  By default this is '/signin-google', you will need to change that default value in your
                //  Google developer settings for your web-app in the "REDIRECT URIS" setting
                CallbackPath = new PathString("/umbraco-google-signin"),                
                Provider = new GoogleOAuth2AuthenticationProvider
                {                    
                    OnAuthenticated = context =>
                    {
                        if (context.Email.EndsWith("@mydomain.com") || context.Email.EndsWith("@mydomain2.com"))
                        {
                            IUserService userService = ApplicationContext.Current.Services.UserService;
                            IUser umbracoUser = userService.GetByEmail(context.Email);
                            if (umbracoUser != null)
                            {
                                Claim idClaim = context.Identity.FindFirst(ClaimTypes.NameIdentifier);
                                Microsoft.AspNet.Identity.UserLoginInfo loginInfo = new Microsoft.AspNet.Identity.UserLoginInfo(idClaim.Issuer, idClaim.Value);
                                BackOfficeUserManager<BackOfficeIdentityUser> userManager = HttpContext.Current.GetOwinContext().GetBackOfficeUserManager();
                                Task<BackOfficeIdentityUser> identityUser = userManager.FindAsync(loginInfo);
    
                                if (identityUser.Result == null)
                                {
                                    userManager.AddLoginAsync(umbracoUser.Id, loginInfo);
                                }
                            }                    
    
                            return Task.FromResult(0);
                        }                                                 
    
                        var errorMessage = string.Format("User tried to log in with {0}, which does not end with an accepted domain name.", context.Email);
                        throw new AuthenticationException(errorMessage);
                    }                    
                }
            };
            googleOptions.ForUmbracoBackOffice(style, icon);
            googleOptions.Caption = caption;
            app.UseGoogleAuthentication(googleOptions);
        }
    
Please Sign in or register to post replies

Write your reply to:

Draft