0

I am implementing OAuth authentication (Google & Facebook) in my .NET API using Entity Framework and JWT tokens. I have already set up my own local authentication system with JWT access tokens and refresh tokens.

My goal is to authenticate users using external providers (Google, Facebook), extract their details, and issue my own JWT tokens instead of using the cookie/token generated by the OAuth middleware.

Current Implementation

I have the following endpoints:

 [HttpGet("google-login")]
    [AllowAnonymous]
    public IActionResult GoogleLogin([FromQuery] string returnUrl)
    {
        var redirectUrl = Url.Action(nameof(GoogleResponse), "Auth", new { returnUrl }, Request.Scheme);
        var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
        return Challenge(properties, GoogleDefaults.AuthenticationScheme);
    }


    [HttpGet("signin-google")]
    [AllowAnonymous]
    public async Task<IActionResult> GoogleResponse([FromQuery] string returnUrl)
    {
        var authenticateResult = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);


        if (!authenticateResult.Succeeded)
            return BadRequest("Google authentication failed.");

        var claims = authenticateResult.Principal.Identities.FirstOrDefault()?.Claims;
        var email = claims?.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value;
        var name = claims?.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
        var key = claims?.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
        var ipAddress = HttpContext.Connection.RemoteIpAddress.MapToIPv6().ToString();

        if (string.IsNullOrEmpty(email))
            return BadRequest("Email not found");


        var result = await authService.SignInWithProviderAsync(email, key, ipAddress, "google");

        return result.Match<IActionResult, OauthResponse>(success =>
        {
            var result = success.Data;

            SetAccessTokenInResponse(result.Jwt);
            SetRefreshTokenInResponse(result.RefreshToken);
            var redirectUri = $"{returnUrl}?access_token={result.Jwt}&refresh_token={result.RefreshToken}";
            return Redirect(redirectUri);
        }, BadRequest);
    }

and this is the program.cs setting for oauth


builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["JwtConfig:Issuer"],
        ValidAudience = builder.Configuration["JwtConfig:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtConfig:Key"]))
    };

    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            context.Token = context.Request.Cookies["tmy209w1"];
            return Task.CompletedTask;
        }
    };
}).AddGoogle(options =>
{
    options.ClientId = builder.Configuration["Authentication:Google:ClientId"];
    options.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];
    options.CallbackPath = "/signin-google";
    options.SaveTokens = false;
}).AddFacebook(options =>
{
    options.ClientId = builder.Configuration["Authentication:Facebook:AppId"];
    options.ClientSecret = builder.Configuration["Authentication:Facebook:AppSecret"];
    options.CallbackPath = "/signin-facebook";
    options.SaveTokens = false;
});

Issue

  • I do not want to use the token/cookie issued by the OAuth middleware since I am handling my own token issuance.

  • However, I keep seeing a persistent cookie named identity.external, and I am unsure why it's being stored and how to prevent it from persisting.

Questions

  1. is identity.external essential ? if so How do I prevent the identity.external cookie from persisting after OAuth authentication?

  2. Is my approach correct for using external authentication while issuing my own JWT tokens

Any insights or corrections to my approach would be greatly appreciated.

4
  • Could you try to delete AspNetCore.Identity.External cookie after ` SetRefreshTokenInResponse(result.RefreshToken);` ? Like : HttpContext.Response.Cookies.Delete(".AspNetCore.Identity.External"); Commented Feb 6 at 10:00
  • You are issuing your own JWT tokens while using external authentication (Google and Facebook), which is generally correct, but requires some additional consideration from a security perspective. Commented Feb 7 at 4:11
  • @JasonPan first thank you for responding , second can you go in detail please? this is my first time dealing with oauth so I do not understand everything clearly Commented Feb 7 at 18:25
  • Hi @Coffee, Sorry for the late reply. Are you still troubled by this problem? If yes, could you create a brand new sample which can reproduce the issue for me, I am willing to check it. Commented Feb 21 at 1:36

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.