Google and Cognito Authentication
Demo: Auth Authz - Google
Prepare Development Certificate
In this tutorial you need to use the development certificate in order to start your application on https.
Different options to start in https
- Use launchSettings.json profiles
dotnet run --launch-profile "https"
- Use an urgument to dotnet run
dotnet run --urls "https://localhost:5001"
- Configure Kestrel in Program.cs or appsettings.json
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseUrls("https://localhost:5001");
var app = builder.Build();
// Configure the HTTP request pipeline.
app.Run();
appsettings.json
Kopiera kod
{
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Setup Google
Prepare the Google Credentials API
Fill in the OAuth Consent information
- Select “External”
Create Credentials
- OAuth client ID
- Web Application
- Authorized redirect URIs:
https://localhost:7131/signin-google
dotnet user-secrets init
dotnet user-secrets set "Authentication:Google:ClientId" "GOOGLE_CLIENT_ID_GOES_HERE"
dotnet user-secrets set "Authentication:Google:ClientSecret" "GOOGLE_CLIENT_SECRET_GOES_HERE"
Configure Google authentication
dotnet add package Microsoft.AspNetCore.Authentication.Google
Configure Authentication middleware in
Program.cs
/Program.cs
... builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() .AddGoogle(options => { options.ClientId = builder.Configuration["Authentication:Google:ClientId"] ?? throw new ArgumentNullException("Authentication:Google:ClientId"); options.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"] ?? throw new ArgumentNullException("Authentication:Google:ClientSecret"); }); ...
Controller
Add two new actions
GoogleLogin()
andGoogleLoginCallbackAsync()
inAccountController.cs
/Controllers/AccountController.cs
... using Microsoft.AspNetCore.Authentication.Google; ... public IActionResult GoogleLogin() { var authProperties = new AuthenticationProperties { RedirectUri = Url.Action("GoogleLoginCallback", "Account") }; return Challenge(authProperties, GoogleDefaults.AuthenticationScheme); } public async Task<IActionResult> GoogleLoginCallbackAsync() { var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); if (!result.Succeeded) { // Handle failure: return to the login page, show an error, etc. return RedirectToAction("Login"); } // Here, you could fetch information from result.Principal to store in your database, // or to find an existing user. return RedirectToAction("Index", "Home"); }
View
Add a new button
Login with Google
in the view fileLogin.cshtml
/Views/Account/Login.cshtml
... <a href="@Url.Action("GoogleLogin", "Account")" class="btn btn-primary">Login with Google</a> ...
Demo: Auth Authz - Cognito
Setup Cognito
- Go to Cognito
- Create User Pool
- Select User name -> Next
- Select No MFA -> Next
- Leave default -> Next
- Select Send email with Cognito -> Next
- Enter User pool name
- Select Use the Cognito Hosted UI
- Enter a Cognito domain (like same as userpool)
- Enter App client name
- Enter Allowed callback URLs (https://localhost:7131/signin-oidc) (Use your port!)
- Expand Advanced app client setttings
- Add Profile to OpenID Connect scopes
- Add Allowed sign-out URLs (https://localhost:7131/) -> Next
- Review -> Create user pool
Configure Cognito authentication
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
Configure Authentication middleware in
Program.cs
/Program.cs
... using Microsoft.AspNetCore.Authentication.OpenIdConnect; ... builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() .AddGoogle(options => { options.ClientId = builder.Configuration["Authentication:Google:ClientId"] ?? throw new InvalidOperationException("Google ClientId is not set."); options.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"] ?? throw new InvalidOperationException("Google ClientSecret is not set."); }) .AddOpenIdConnect(options => { options.ClientId = builder.Configuration["Authentication:Cognito:ClientId"] ?? throw new InvalidOperationException("Cognito ClientId is not set."); options.ResponseType = builder.Configuration["Authentication:Cognito:ResponseType"] ?? throw new InvalidOperationException("Cognito ResponseType is not set."); options.MetadataAddress = builder.Configuration["Authentication:Cognito:MetadataAddress"] ?? throw new InvalidOperationException("Cognito MetadataAddress is not set."); options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProviderForSignOut = context => { context.ProtocolMessage.Scope = builder.Configuration["Authentication:Cognito:Scope"] ?? throw new InvalidOperationException("Cognito Scope is not set."); context.ProtocolMessage.ResponseType = builder.Configuration["Authentication:Cognito:ResponseType"] ?? throw new InvalidOperationException("Cognito ResponseType is not set.");; // context.ProtocolMessage.IssuerAddress = CognitoHelpers.GetCognitoLogoutUrl(builder.Configuration, context.HttpContext); // Create Cognito logout URL var cognitoDomain = builder.Configuration["Authentication:Cognito:CognitoDomain"] ?? throw new InvalidOperationException("Cognito CognitoDomain is not set."); var clientId = builder.Configuration["Authentication:Cognito:ClientId"] ?? throw new InvalidOperationException("Cognito ClientId is not set."); var appSignOutUrl = builder.Configuration["Authentication:Cognito:AppSignOutUrl"] ?? throw new InvalidOperationException("Cognito AppSignOutUrl is not set."); var logoutUrl = $"{context.Request.Scheme}://{context.Request.Host}{appSignOutUrl}"; var cognitoLogoutUrl = $"{cognitoDomain}/logout?client_id={clientId}&logout_uri={logoutUrl}"; context.ProtocolMessage.IssuerAddress = cognitoLogoutUrl; // Close authentication sessions context.Properties.Items.Remove(CookieAuthenticationDefaults.AuthenticationScheme); context.Properties.Items.Remove(OpenIdConnectDefaults.AuthenticationScheme); return Task.CompletedTask; } }; }); ...
Appsettings
Go to the App integration tab
- Modify MetadataAddress with AWS Region and UserPoolID (User pool overview)
- Set the Cognito Domain
- Set the ClientID
dotnet user-secrets set "Authentication:Cognito:ClientId" "COGNITO_CLIENT_ID_GOES_HERE"
/appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Authentication": {
"Cognito": {
"ClientId": "COGNITO_CLIENT_ID_GOES_HERE",
"ResponseType": "code",
"MetadataAddress": "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_dKrElOUfh/.well-known/openid-configuration",
"Scope": "openid",
"AppSignOutUrl": "/",
"CognitoDomain": "https://aspnetintegration.auth.eu-west-1.amazoncognito.com"
},
"Google": {
"ClientId": "GOOGLE_CLIENT_ID_GOES_HERE",
"ClientSecret": "GOOGLE_CLIENT_SECRET_GOES_HERE"
}
}
}
Controller
Add a new action
CognitoLogin()
inAccountController.cs
/Controllers/AccountController.cs
... using Microsoft.AspNetCore.Authentication.OpenIdConnect; ... public IActionResult CognitoLogin() { // Challenge the Cognito authentication scheme return Challenge( new AuthenticationProperties { RedirectUri = Url.Action("Index", "Home") }, OpenIdConnectDefaults.AuthenticationScheme); }
Add
OpenIdConnectDefaults.AuthenticationScheme
to Signout/Controllers/AccountController.cs
... [Authorize] public IActionResult Logout() { return SignOut( new AuthenticationProperties { RedirectUri = Url.Action("Index", "Home") }, CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme); }
View
Add a new button
Login with Cognito
in the view fileLogin.cshtml
/Views/Account/Login.cshtml
... <a href="@Url.Action("CognitoLogin", "Account")" class="btn btn-primary" >Login with Cognito</a> ...