If you refer to https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x?view=aspnetcore-2.2 you can see you can configure OpenID Connect (OIDC) authentication for various providers as below:
services.AddAuthentication()
.AddFacebook(options =>
{
options.AppId = Configuration["auth:facebook:appid"];
options.AppSecret = Configuration["auth:facebook:appsecret"];
});
services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = Configuration["auth:google:clientid"];
options.ClientSecret = Configuration["auth:google:clientsecret"];
});
Microsoft
services.AddAuthentication()
.AddMicrosoftAccount(options =>
{
options.ClientId = Configuration["auth:microsoft:clientid"];
options.ClientSecret = Configuration["auth:microsoft:clientsecret"];
});
My question is does anybody have the settings I would need to provide to Support Amazon and Evernote OIDC?
To enable Two-Step Verification:In Your Account, select Login & security. Select Edit beside Two-Step Verification (2SV) Settings. Click Get Started. Follow the on-screen instructions.
Choose Login & Security Click Edit next to Two-Step Verification (2SV) Settings. In the Enrolled 2SV Authenticators section, click Add new phone or Authenticator App. Complete two-step verification by receiving an OTP via voice call. Enter the OTP you received and the Add backup method page will open.
You can find Login with Amazon reference here
Amazon still does not support OIDC, but supports OAuth. However the default OAuthHandler
for dotnet does not provide UserInfoEndpoint
handling. That's why you have to either implement the call to UserInfoEndpoint
(can grab it from oidc) or hack the OIDC to make it thinking that it has id_token whenever it has not. I've passed the second route. Little bit dirty trick, but I've got my user identified.
.AddOpenIdConnect("lwa", "LoginWithAmazon", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.Authority = "https://www.amazon.com/";
options.ClientId = "amzn1.application-oa2-client.xxxxxxxxxxxxxx";
options.ClientSecret = "xxxxxxxxxxxxxxxxx";
options.ResponseType = "code";
options.ResponseMode = "query";
options.SaveTokens = true;
options.CallbackPath = "/signin-amazon";
options.SignedOutCallbackPath = "/signout-callback-amazon";
options.RemoteSignOutPath = "/signout-amazon";
options.Scope.Clear();
options.Scope.Add("profile");
options.GetClaimsFromUserInfoEndpoint = true;
var rsa = RSA.Create();
var key = new RsaSecurityKey(rsa){KeyId = "1"};
var jwtClaims = new List<Claim>
{
new Claim(JwtClaimTypes.IssuedAt, "now"),
new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()),
new Claim(JwtClaimTypes.Subject, Guid.NewGuid().ToString())
};
var jwt = new JwtSecurityToken(
"issuer",
"audience",
jwtClaims,
DateTime.UtcNow,
DateTime.UtcNow.AddHours(1),
new SigningCredentials(key, "RS256"));
var handler = new JwtSecurityTokenHandler();
handler.OutboundClaimTypeMap.Clear();
var token = handler.WriteToken(jwt);
options.Configuration = new OpenIdConnectConfiguration
{
AuthorizationEndpoint = "https://www.amazon.com/ap/oa",
TokenEndpoint = "https://api.amazon.com/auth/o2/token",
UserInfoEndpoint = "https://api.amazon.com/user/profile"
};
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateTokenReplay = false,
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
IssuerSigningKey = key
};
AuthorizationCodeReceivedContext hook = null;
options.Events = new OpenIdConnectEvents
{
OnAuthenticationFailed = async context =>
{
//context.SkipHandler();
},
OnAuthorizationCodeReceived = async context => { hook = context; },
OnTokenResponseReceived = async context =>
{
context.TokenEndpointResponse.IdToken = token;
hook.TokenEndpointResponse = context.TokenEndpointResponse;
},
OnUserInformationReceived = async context =>
{
var user = context.User;
var claims = new[]
{
new Claim(JwtClaimTypes.Subject, user["user_id"].ToString()),
new Claim(JwtClaimTypes.Email, user["email"].ToString()),
new Claim(JwtClaimTypes.Name, user["name"].ToString())
};
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims));
context.Success();
}
};
})
Unfortunately, neither Login with Amazon nor Evernote supports Open ID Connect. Other mentioned services do, which can be verified by visiting appropriate configuration site of each of them: Google, Microsoft.
There are ofc others that are not preconfigured in .Net and can be used with it: Salesforce
As you probably noticed usually the configuration for Open ID Connect is stored on a site with "/.well-known/openid-configuration" suffix. This is called OpenID Connect metadata document and it contains most of the information required for an app to do sign-in. This includes information such as the URLs to use and the location of the service's public signing keys.
And now lets go for .Net configuration for custom Open ID Connect provider (I will use Salesforce as it supports Open ID):
services.AddAuthentication()
.AddFacebook(options =>
{
options.AppId = Configuration["auth:facebook:appid"];
options.AppSecret = Configuration["auth:facebook:appsecret"];
})
.AddOpenIdConnect("OpenIdConnectSalesforce", "Salesforce", options =>
{
options.Authority = "https://login.salesforce.com";
options.ClientId = Configuration["auth:salesforce:appid"];
options.ClientSecret = Configuration["auth:salesforce:appsecret"];
options.ResponseType = "code";
});
And after launching web app we can see additional button to log in using Salesforce:
As for Evernote and Amazon you could use their SDKs and APIs to implement their log in methods respectively. I do believe that they support OAuth.
Extended the solution by @d-f to use OAuth handler.
.AddOAuth("lwa-oauth", "OauthLoginWithAmazon", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "amzn1.application-oa2-client.zzzzzzzzzzzz";
options.ClientSecret = "4c0630b4166c901519a730835ezzzzzzzzzzzzzzzz";
options.SaveTokens = true;
options.CallbackPath = "/signin-amazon";
options.Scope.Clear();
options.Scope.Add("profile");
options.AuthorizationEndpoint = "https://www.amazon.com/ap/oa";
options.TokenEndpoint = "https://api.amazon.com/auth/o2/token";
options.UserInformationEndpoint = "https://api.amazon.com/user/profile";
options.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
var accessToken = context.AccessToken;
HttpResponseMessage responseMessage =
await context.Backchannel.SendAsync(
new HttpRequestMessage(HttpMethod.Get, options.UserInformationEndpoint)
{
Headers =
{
Authorization = new AuthenticationHeaderValue("Bearer", accessToken)
}
});
responseMessage.EnsureSuccessStatusCode();
string userInfoResponse = await responseMessage.Content.ReadAsStringAsync();
var user = JObject.Parse(userInfoResponse);
var claims = new[]
{
new Claim(JwtClaimTypes.Subject, user["user_id"].ToString()),
new Claim(JwtClaimTypes.Email, user["email"].ToString()),
new Claim(JwtClaimTypes.Name, user["name"].ToString())
};
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims));
context.Success();
}
};
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With