Search code examples
authenticationasp.net-coregoogle-oauthgoogle-openidasp.net-core-identity

Using Google OAuth to secure web services in aspnet core


I'm getting lost in OAuth and OpenIDConnect and aspnet core middleware. Any help on this would be appreciated.

I have multiple UIs (web, native apps) that use the same set of web services, and I'd like to ensure only authenticated users can access the web services. My organization uses Google accounts, so I'd like to use Google authentication restricted to the organization domain.

The web site is properly requiring authentication, following this sample. What I need now is to have the web site (AngularJS 4) invoke my back end web services with an auth token that I can verify with Google.

The back end services are written with aspnet core. I've tried using these approaches: Google middleware and Google OpenIDConnect but these still 1) assume there is a UI that can prompt an unauthorized user to log in, and 2) appear to be cookie-based, and I won't have cookies for the web service calls.

I don't want to prompt the user to log in, since the "user" in this case is a software client. Either they're authenticated or not already. I just need to get the authentication token, validate it, and carry on.

This appears to be the same question, which hasn't been answered yet, either.

Any suggestions are appreciated. Also, suggestions or tips on having native apps do the same!


Solution

  • Got it working. As mentioned, I was getting lost, and the OpenIDConnect, though referenced in several areas as a solution, was a red herring for the web services. Here's what is working for me now, with as complete steps as I can provide (some cleanup required):

    1. Add authentication to the UI following these directions
    2. Obtain the JWT token as shown in the first segment here
    3. On each web service call, include the JWT token in the headers:

      Name: Authentication

      Value: Bearer {token value}

    4. Install the JwtBearer NuGet package

    5. In the ConfigureServices method of Startup in the web service, after you AddMvc():

          services.AddAuthorization(options =>
      {   // this policy needed only if you want to restrict to accounts within your domain. otherwise, don't use options. or use whatever options work for you.
              options.AddPolicy("hd",
                  policy => policy.RequireAssertion(context =>
                      context.User.HasClaim(c =>
                          c.Type == "hd" &&
                          ("https://accounts.google.com".Equals(c.Issuer) ||
                           "accounts.google.com".Equals(c.Issuer, StringComparison.CurrentCultureIgnoreCase)) &&
                          c.Value == "yourdomain.com"
                      )));
      });
      
    6. In the Configure method, before you UseMvc():

              JwtBearerOptions jwtOptions = new JwtBearerOptions();
              jwtOptions.Audience = "{the OAuth 2.0 client ID credential from google api developer console}";
              jwtOptions.Authority = "https://accounts.google.com";
              jwtOptions.TokenValidationParameters = new TokenValidationParameters();
              jwtOptions.TokenValidationParameters.ValidIssuers = new List<string>()
              {
                  "https://accounts.google.com",
                  "accounts.google.com"
              };
      
              app.UseJwtBearerAuthentication(jwtOptions);
      

    Perhaps there is a more appropriate way to do this...if there is, I'm interested in trying it out. For now, this is working.