Christopher
Christopher

Reputation: 315

Blazor server : Struggling to add policy to Google authentication to restrict access to my account only

After successfully making my app authenticate my app with Google, I am trying to add a policy which will only restrict access to my google account.

I used this tutorial to get google authentication working : https://www.youtube.com/watch?v=H4G0kqIG1_0

and I refered to this stack overflow question to add my policy:

ASP.NET Core authentication with Google only for a specific account

The answer to this question didn't seem to work out for me, my attempt to get the claim returns a null value and I don't know why.

below is the relevant code on Startup.cs

services.AddAuthentication("Cookies")
                .AddCookie(opt =>
                {
                    opt.Cookie.Name = "GoogleAuth";
                    opt.LoginPath = "/auth/google-login";
                })
                .AddGoogle(opt =>
                {
                    opt.ClientId = Environment.GetEnvironmentVariable("GOOGLE_CLIENT_ID");
                    opt.ClientSecret = Environment.GetEnvironmentVariable("GOOGLE_CLIENT_SECRET");
                    opt.Scope.Add("openid");
                    opt.Scope.Add("profile");
                    opt.Scope.Add("email");
                    opt.Events.OnCreatingTicket = context =>
                    {
                        string picture = context.User.GetProperty("picture").GetString();
                        string name = context.User.GetProperty("name").GetString();
                        string given_name = context.User.GetProperty("given_name").GetString();

                        context.Identity.AddClaim(new Claim("picture", picture));
                        context.Identity.AddClaim(new Claim("name", name));
                        context.Identity.AddClaim(new Claim("given_name", given_name));
                        return Task.CompletedTask;
                    };
                });

services.AddAuthorization(opt =>
            {
                opt.AddPolicy("MeOnly", policy =>
                {
                    policy.RequireAssertion(context =>
                    {
                        // returns a null value
                        var name = context.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value;

                        /*
                         *  I want to add some logic to only give access to my Google account
                         */
                        return false;
                    });
                });
            });

Upvotes: 0

Views: 511

Answers (1)

abdusco
abdusco

Reputation: 11101

You can restrict access by account id or email claim (or any other claim, for that matter).

Create a policy and require a specific claim value. Here I'm using a FallbackPolicy which ensures all endpoints are protected with this policy unless specified otherwise.

services.AddAuthorization(options =>
    options.FallbackPolicy = new AuthorizationPolicyBuilder(
            GoogleDefaults.AuthenticationScheme
        )
        .RequireAuthenticatedUser()
        .RequireClaim(ClaimTypes.Email, "[email protected]")
        .Build()
);

It might be useful to make this configurable. Add this to appsettings.json

{
  "AuthorizedEmails": [
    "[email protected]",
    "[email protected]"
  ],
  // ...
}

Then we can read this configuration at runtime and apply it:

var authorizedEmails = Configuration.GetSection("AuthorizedEmails").Get<string[]>();
services.AddAuthorization(options =>
    options.FallbackPolicy = new AuthorizationPolicyBuilder(
            GoogleDefaults.AuthenticationScheme
        )
        .RequireAuthenticatedUser()
        .RequireClaim(ClaimTypes.Email, authorizedEmails)
        .Build()
);

Further info

Upvotes: 2

Related Questions