I am trying to implement Oauth in my .net API with EntityFramework. I already completed the custom local authentication with JWT tokens and refresh tokens. I got a little bit confused as to how I would approach it.
Here is my implementation for the Google Oauth system (I also use Facebook Oauth but it's kinda the same thing):
[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; });
I am not sure if this is how it's supposed to go so correct me if anything is wrong with the implementation.
I don't want to use the token / cookie that the Oauth middleware issues because I already have a custom token that I want to issue to the user, but I keep finding this persistent cookie name identity.external and I don't know why it's persisting.
Please help me get this to work properly the way it's meant to work.
ConfigureApplicationCookie
andConfigureExternalCookie
to configure cookies.\$\endgroup\$