Umbraco 7.3+ and OAuth 2.0

This document details how to set up Umbraco 7.3+ with OAuth 2.0

Before we can start we need to set up our project:

  1. Start with a new MVC5 project.
  2. Add Umbraco 7.3 or higher to the project.
  3. Run the project and set up Umbraco.
  4. Create a Google app on the Google developer console (https://console.developers.google.com)

After creating the App on the Google developer console make sure to add the proper redirect URI.
This is the address of your server followed by /signin-google.

step14

Once the project is set up we need to make some changes. After installing Umbraco, the standard Startup class is no longer executed. Instead, Umbraco it’s own UmbracoDefaultOwinStartup class is executed. We are going to take back control by making the Startup class inherit from UmbracoDefaultOwinStartup and then changing the web.config file to execute our class instead of the UmbracoDefaultOwinStartup class.

First make the Startup class inherit from UmbracoDefaultOwinStartup and add the following code to it:

base.Configuration(app);
ConfigureAuth(app);

It’s important that base.Configuration is called before setting the OAUTH cookies with ConfigureAuth.

[assembly: OwinStartupAttribute(typeof(umbracotestproject.Startup))]
namespace umbracotestproject
{
    public partial class Startup : UmbracoDefaultOwinStartup 
    {
        public override void Configuration(IAppBuilder app)
        {
            base.Configuration(app);
            ConfigureAuth(app);
        }
    }
}

Now we need to change the owin:appStartup key. Instead of the UmbracoDefaultOwinStartup class we have to add our own Startup class.

<appSettings>
 <add key="umbracoConfigurationStatus" value="7.3.0" />
 <add key="umbracoReservedUrls" value="~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd" />
 <add key="umbracoReservedPaths" value="~/umbraco,~/install/" />
 <add key="umbracoPath" value="~/umbraco" />
 <add key="umbracoHideTopLevelNodeFromPath" value="true" />
 <add key="umbracoUseDirectoryUrls" value="true" />
 <add key="umbracoTimeOutInMinutes" value="20" />
 <add key="umbracoDefaultUILanguage" value="en" />
 <add key="umbracoUseSSL" value="false" />
 <add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
 <add key="webpages:Enabled" value="false" />
 <add key="enableSimpleMembership" value="false" />
 <add key="autoFormsAuthentication" value="false" />
 <add key="log4net.Config" value="config\log4net.config" />
 <add key="owin:appStartup" value="umbracotestproject.Startup" />
 </appSettings>

Now that our own Startup class is executed, we can enable OAUTH. In order to do this we need to uncomment some code that is already present in the Startup.Auth file.

 //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
 //{
 // ClientId = "",
 // ClientSecret = ""
 //});

Uncomment the app.UseGoogleAuthentication code and fill in the ClientId and ClientSecret of your Google App.

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = "",
ClientSecret = ""
});

Change the AccountController so that it inherits from the Umbraco SurfaceController.


[Authorize]
public class AccountController : SurfaceController
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;

// Removed code for improved readability for this tutorial
}

In my own project I had to remove the forms authentication code from the Web.Config file.

<!-- <authentication mode="Forms">
<forms name="yourAuthCookie" loginUrl="login.aspx" protection="All" path="/" />
</authentication> -->
<authorization>
<allow users="?" />
</authorization>

In order to show the Google login button we can add the following code to our master template:

if (Members.IsLoggedIn())
{
Html.RenderPartial("~/Views/Account/_ExternalLoggedInPartial.cshtml", Model);
}
else
{
<section id="socialLoginForm">
@Html.Partial("~/Views/Account/_ExternalLoginsListPartial.cshtml", new ExternalLoginListViewModel { ReturnUrl = Model.Url })
</section>
}

Build and run the project and see if you can login using Google.

Martin de Boer

Martin de Boer

Martin de Boer is a .NET developer at Indivirtual. Currently specializing himself in the magical art of Umbraco.

  • James Strugnell

    Hi Martin, thanks for this article.

    I tried this but using Azure AD rather than Google. I can authenticate with Azure AD but when I am returned to the site it calls the ExternalLoginCallback method. Within there it tries to call SignInManager.ExternalSignInAsync but an exception is raised at that point as it can’t find the User Logins table for ASP.Net Identity – e.g. “Invalid object name ‘dbo.AspNetUserLogins'”. Did you have and/or overcome this issue at all? Did you not need to use the UmbracoIdentity package to enable this functionality? e.g. https://github.com/Shazwazza/UmbracoIdentity

    Thanks,
    James.

    • Martin de Boer

      Hello James, I did not use the UmbracoIdentity package. As I understand it this is no longer necessary with Umbraco 7.3. It seems you have a problem with your database. Maybe this helps. In my project I enabled automatic migrations by typing Enable-Migrations on the Package Manager Console. This will generate the file Configuration.cs. Here I set AutomaticMigrationsEnabled to true. I then store my Identity data in the same database as Umbraco by changing the first parameter of the ApplicationDbContext constructor to the name of the connection string defined in web.config.

      • James Strugnell

        Thanks for the reply Martin. Your guidance did get me further along the process. I think the UmbracoIdentity package configures ASP.Net Identity to use the Umbraco Member tables rather than creating the default ASP.Net Identity tables, as happens in your scenario. With your approach I couldn’t login to Umbraco as a member. I think I need to spend some more time familiarizing myself with ASP.Net Identity to be honest.

      • madura silva

        Hi Martin. I have tried your steps many times but it did not generate dbo.AspNet* tables in the database. Would you please explain this please

        • Martin de Boer

          It seems I have forgotten a step in the tutorial. Automatic migrations needs to be enabled for this. Type Enable-Migrations in the package manager console. Then use update-database -v -f for each update in the database structure. I will adjust the tutorial.

  • madura silva

    Hi Martin, How can we authenticate a user from Azure AD / office 365 with this?

    • Martin de Boer

      I’m sorry but I don’t have any experience with Umbraco + Azure AD / office 365 at the moment.

  • Giorgos Papadakis

    Hi Martin, I have been trying to create the google login for several days but I did not make it work. I do not know what else I have to do. I have spent several hours trying to make it work but I suppose there is something that I have not done as it is supposed to do. I have no experience in owin and I guess this is the reason that I can not make it work. Is it possible to create an example with an Umbraco installation and make it available to download so that I will see how I am supposed to make it.

    Thanks in advance
    Giorgos

  • Pedro Almeida

    Anyone have a complete example of a solution with Umbraco and OAuth2 login (Facebook or Google) ?

  • Pedro Almeida

    @disqus_AS1xsH7MSz:disqus could you you provide the source code from an example ?

  • Evan Legor

    Hi, I’m a total newbie. I have no prior knowledge in umbraco, the language that is being used in it, or even the db server that is incorporated to it. So I’m a bit lost here.

    you said:
    “First make the Startup class inherit from UmbracoDefaultOwinStartup and add the following code to it:”

    and I have no idea where can I create a Startup class.

    Now I know that I should have some prior or basic knowledge but I’m on a tight sched and had to create a SSO function. I’m hoping you can explain on where to I have to put this codes. what kind of file? or maybe you could suggest a good editor for it. Something like eclipse that has a hint functionality where you can find description for classes.