2014-11-04 3 views
4

Я просмотрел много документации Google и SO Q/A, но не повезло. Интересно, успешно ли кто-либо успешно использовал миграцию OpenId для OpenId Connect в соответствии с рекомендациями Google.Миграция Google OpenId Connect: получение openid_id в приложении ASP.NET

Это то, что мы привыкли делать:

IAuthenticationResponse response = _openid.GetResponse(); 
if (response != null) { 
    //omitted for brevity  
} else { 
    IAuthenticationRequest req = _openid.CreateRequest("https://www.google.com/accounts/o8/id"); 
    req.AddExtension(new ClaimsRequest 
        { 
         Country = DemandLevel.Request, 
         Email = DemandLevel.Request, 
         Gender = DemandLevel.Require, 
         PostalCode = DemandLevel.Require, 
         TimeZone = DemandLevel.Require 
        }); 
    req.RedirectToProvider(); 
} 

Это было сделано с использованием версии DotNetOpenAuth, которая восходит несколько лет. Поскольку Google устарела аутентификация OpenId, мы пытаемся перейти на OpenID Connect. Ключевым вопросом здесь является вопрос: могу ли я каким-то образом получить идентификатор OpenId (в форме https://www.google.com/accounts/o8/id?id=xyz), используя последнюю версию библиотеки DotNetOpenAuth или любым другим способом?

Я пробовал последний DotNetOpenAuth, и я могу заставить его работать, но он дает мне новый идентификатор (это ожидалось). Я также пробовал путь Javascript, используя этот URL (разрывы строк для readibility):

https://accounts.google.com/o/oauth2/auth? 
    scope=openid%20profile%20email 
    &openid.realm=http://localhost/palkkac/ 
    &client_id=//here is the client id I created in google developer console 
    &redirect_uri=http://localhost/palkkac/someaspxpagehere 
    &response_type=id_token%20token 

Я проверил (с помощью Fiddler) значение области действия, которые мы в настоящее время отправки с помощью старого кода DotNetOpenAuth и это http://localhost/palkkac/. Я поставил ту же область в url выше. URL-адрес перенаправления начинается с с вещественным значением, но это не совсем то же самое.

Когда я перенаправлять на простую страницу, которая разбирает id_token и расшифровывает его (с помощью https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=zyx конечной точки), я получаю это:

audience "client id is here" 
email "[email protected]" 
expires_in 3597 
issued_at //some numbers here 
issued_to "client id is here" 
issuer "accounts.google.com" 
user_id  "here is a sequence of numbers, my id in the OpenID Connect format that is" 
verified_email true 

Так что нет никаких признаков openid_id поле, которое можно было бы ожидать, чтобы найти здесь, хотя вся структура сообщения отличается от документов Google, например, нет подзаголовка под названием. Интересно, действительно ли я использую неправильную конечную точку, параметры или что-то еще?

То, что я читал, является руководством по миграции: https://developers.google.com/accounts/docs/OpenID. Я пропустил шаг 2, потому что он казался необязательным шагом. На шаге 3 обсуждается поле openid_id, и я хотел бы, чтобы это сначала работало как доказательство концепции.

Мы зарегистрировали приложение в Google, чтобы создать идентификатор клиента и т. Д. В настоящее время также имеется множество разрешенных URL-адресов перенаправления, а также источников javascript, перечисленных в консоли Google dev. Дайте мне знать, если это может испортить систему, и я отправлю их здесь для ознакомления.

Замечание: мы должны перемещать наше приложение за строго защищенной межсетевой защитой средой, где нам нужно будет открывать порты, чтобы сделать это на стороне сервера. Таким образом, было бы предпочтительным решение Javascript на стороне клиента для доступа к Google в сочетании с HTTPS и перенаправление результата на сервер (если нет других проблем, которые говорят против этого).

Есть и другие ресурсы на SO относительно этого же вопроса, хотя все они, кажется, используют различные библиотеки на стороне сервера, чтобы сделать работу, и никто, кажется, не сделал никаких попыток с помощью Javascript:

  • Здесь (https://stackoverflow.com/questions/22842475/migrating-google-openid-to-openid-connect-openid-id-does-not-match) Я думаю, проблема была решена, установив область таким же, как в старом потоке OpenId2.0. Это, похоже, не работает в моем случае.
  • here Поле openid_id также отсутствует, но проблема здесь заключается в том, как запрашивать id_token из Google, используя библиотеки, отличные от DotNetOpenAuth.
  • и в here, похоже, подобные проблемы заставляют Google возвращать поле openid_id.
+0

Мы также не смогли найти решение этой проблемы после более чем месяца поиска. – spadelives

+0

@spadelives Я вижу, что вы, наконец, выяснили, как отправить параметр realm с помощью Owin и ASP.NET MVC (ссылаясь на ваш вопрос SO). Но вы все еще не получаете оба идентификатора, это так? – mikkark

+0

да, я получаю оба идентификатора, используя решение, предлагаемое cortex93 – spadelives

ответ

2

Вы можете использовать промежуточное ПО GoogleAuthentication owin.

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions 
{ 
    SignInAsAuthenticationType = signAs, 
    AuthenticationType = "Google", 
    ClientId = "xxx.apps.googleusercontent.com", 
    ClientSecret = "xx", 
    CallbackPath = PathString.FromUriComponent("/oauth2callback"), 
    Provider = new GoogleOAuth2AuthenticationProvider 
    { 
     OnApplyRedirect = context => 
     { 
      context.Response.Redirect(context.RedirectUri + "&openid.realm=https://mydomain.com/"); // DotNetOpenAuth by default add a trailing slash, it must be exactly the same as before 
     } 
    }, 
    BackchannelHttpHandler = new MyWebRequestHandler() 
} 

Затем добавьте новый класс с именем MyWebRequestHandler:

public class MyWebRequestHandler : WebRequestHandler 
    { 
     protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      var httpResponse = await base.SendAsync(request, cancellationToken); 
      if (request.RequestUri == new Uri("https://www.googleapis.com/plus/v1/people/me")) return httpResponse; 

      var configuration = await OpenIdConnectConfigurationRetriever.GetAsync("https://accounts.google.com/.well-known/openid-configuration", cancellationToken); // read the configuration to get the signing tokens (todo should be cached or hard coded) 

      // google is unclear as the openid_id is not in the access_token but in the id_token 
      // as the middleware dot not expose the id_token we need to parse it again 
      var jwt = httpResponse.Content.ReadAsStringAsync().Result; 
      JObject response = JObject.Parse(jwt); 
      string idToken = response.Value<string>((object)"id_token"); 

      JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); 

      try 
      { 
       SecurityToken token; 
       var claims = tokenHandler.ValidateToken(idToken, new TokenValidationParameters() 
       { 
        ValidAudience = "xxx.apps.googleusercontent.com", 
        ValidIssuer = "accounts.google.com", 
        IssuerSigningTokens = configuration.SigningTokens 
       }, out token); 

       var claim = claims.FindFirst("openid_id"); 
       // claim.Value will contain the old openid identifier 
       if (claim != null) Debug.WriteLine(claim.Value); 
      } 
      catch (Exception ex) 
      { 
       Debug.WriteLine(ex.ToString()); 
      } 
      return httpResponse; 
     } 
    } 

Если, как мне вы нашли это на самом деле не просто, пожалуйста, помочь upvoting этого вопроса https://katanaproject.codeplex.com/workitem/359

+0

Если я не совсем ошибаюсь, этот ответ является специфичным для ASP.NET MVC? Наше приложение представляет собой простой ASP.NET, хотя эта же общая идея все же должна применяться. – mikkark

+0

Хорошо, так что кусок кода не является spcific для MVC. Я не очень хорошо знаком с OWIN, поэтому я понял это неправильно. Я могу подтвердить, что я действительно могу получить старый идентификатор, используя код из коры. Теперь я хотел бы знать, как именно получить этот код Owin для работы с ASP.NET (не MVC) и «сбоку» вместе с нашими текущими механизмами аутентификации. Кроме того, наше приложение - .net 4.0, поэтому использование Owin потребует обновления структуры. – mikkark

+0

Мне удалось заставить это работать в простой ASP.NET. Мы используем стороннюю библиотеку аутентификации на основе SAML, которая, похоже, немного запуталась. После того как я удалил его, я получил это, чтобы работать.Это может работать как на самом деле, потому что у нас есть две установки на разных серверах, и один из них использует SAML, а другой будет использовать OAuth и без SAML. Тем не менее, я хотел бы заставить их работать вместе, по крайней мере, понять, почему они не работают сейчас. – mikkark

Смежные вопросы