Настройки аутентификации для Amazon и Evernote - PullRequest
5 голосов
/ 18 апреля 2019

Если вы ссылаетесь на https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x?view=aspnetcore-2.2, вы можете увидеть, что можете настроить аутентификацию OpenID Connect (OIDC) для различных провайдеров, как показано ниже:

Facebook

services.AddAuthentication()
        .AddFacebook(options =>
        {
            options.AppId = Configuration["auth:facebook:appid"];
            options.AppSecret = Configuration["auth:facebook:appsecret"];
        });

Google

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"];
        });

У меня вопрос: есть ли у кого-нибудь настройки, которые мне нужно было бы предоставить для поддержки Amazon и Evernote OIDC?

Ответы [ 3 ]

4 голосов
/ 25 апреля 2019

Вы можете найти логин с ссылкой на Amazon здесь
Amazon по-прежнему не поддерживает OIDC, но поддерживает OAuth.Однако значение по умолчанию OAuthHandler для dotnet не обеспечивает обработку UserInfoEndpoint.Вот почему вы должны либо реализовать вызов UserInfoEndpoint (можете получить его из oidc), либо взломать OIDC, чтобы заставить его думать, что он имеет id_token всякий раз, когда его нет.Я прошел второй маршрут.Немного подвох, но я опознал своего пользователя.

.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();
       }
  };
})
3 голосов
/ 23 апреля 2019

К сожалению, ни Login с Amazon, ни Evernote не поддерживают Open ID Connect. Другие упомянутые сервисы делают, что можно проверить, посетив соответствующий сайт конфигурации каждого из них: Google , Microsoft .

Есть и другие, которые предварительно не настроены в .Net и могут использоваться с ним: Salesforce

Как вы, вероятно, заметили, обычно конфигурация для Open ID Connect хранится на сайте с суффиксом "/.well-known/openid-configuration". Это называется документ метаданных OpenID Connect, и он содержит большую часть информации, необходимой приложению для входа в систему. Сюда входит такая информация, как используемые URL-адреса и расположение открытых ключей подписи службы.

А теперь давайте перейдем к настройке .Net для настраиваемого поставщика Open ID Connect (я буду использовать Salesforce, поскольку он поддерживает 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";
});

И после запуска веб-приложения мы видим дополнительную кнопку для входа в систему с помощью Salesforce: enter image description here

Что касается Evernote и Amazon, вы можете использовать их SDK и API для реализации их методов входа в систему соответственно. Я верю, что они поддерживают OAuth.

1 голос
/ 27 апреля 2019

Расширенное решение с помощью @ d-f для использования обработчика OAuth.

.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();
       }
   };
})
...