2014-11-04 9 views
4

많은 Google 문서와 SO Q/A를 사용했지만 운이 없었습니다. OpenId Connect to OpenId Connect 마이 그 레이션을 Google이 권고 한 바에 따라 성공적으로 사용하고 있는지 궁금합니다.Google OpenId Connect 마이그레이션 : ASP.NET 응용 프로그램에서 openid_id 가져 오기

이것은 우리가하는 데 사용되는 것입니다 : 몇 년 전으로 거슬러 올라간다 DotNetOpenAuth의 버전을 사용하여 수행되었다

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

. Google은 OpenID 인증을 사용하지 않으므로 OpenID Connect로 이전하려고합니다. 여기서 핵심 질문은 : DotNetOpenAuth 라이브러리의 최신 버전을 사용하거나 다른 방법을 사용하여 OpenId 식별자 (https://www.google.com/accounts/o8/id?id=xyz 형태로)를 어떻게 든 사용할 수 있습니까?

나는 최신 DotNetOpenAuth를 시도했지만 작동하도록 할 수는 있지만 새로운 ID를 제공합니다 (예상). 또한 (라인 일기 좋게하기위한 나누기)이 URL을 사용하여 자바 스크립트 방법을 시도 :

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 

는 우리가 현재 이전 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 문서와 다르게 보이지만 예를 들어 sub라는 필드는 없습니다. 내가 실제로 잘못된 종단점, 매개 변수 또는 다른 것을 사용하고 있는지 궁금합니다.

제가 읽은 안내서는 https://developers.google.com/accounts/docs/OpenID입니다. 옵션 단계와 같아서 2 단계를 건너 뛰었습니다. 3 단계에서 openid_id 필드에 대해 설명하고이를 개념 증명 개념으로 사용하고자합니다.

클라이언트 ID 등을 만들기 위해 Google에 앱을 등록했습니다. 이제 Google 개발 콘솔에 나열된 자바 스크립트 원본뿐만 아니라 수많은 허용 된 리디렉션 URL이 있습니다. 시스템이 엉망이 될지 알려면 검토를 위해 여기에 게시 해 드리겠습니다.

사이드 노트 : 서버 측에서이 작업을 수행하기 위해 포트를 열어야하는 엄격한 방화벽 환경에서 앱을 이전해야합니다. 따라서 HTTPS와 결합 된 Google에 액세스하고 결과를 서버로 리디렉션하는 클라이언트 측 Javascript 솔루션이 선호됩니다 (이와 반대되는 다른 문제가없는 한). 이러한 모든 작업을 수행하는 서버 측에서 다른 라이브러리를 사용하는 것 아무도 자바 스크립트 사용에 어떤 시도를 한 것 같다 있지만 SO이 같은 문제에 대한 다른 자원이있다

:

  • 여기 (https://stackoverflow.com/questions/22842475/migrating-google-openid-to-openid-connect-openid-id-does-not-match) 문제는 이전 OpenId2.0 흐름에서와 같은 영역을 설정하여 해결 된 것 같아요. 이건 내 경우에는 효과가없는 것 같아.
  • 이상 here openid_id 필드도 빠졌지 만 여기서는 DotNetOpenAuth 이외의 라이브러리를 사용하여 Google에서 id_token을 요청하는 방법에 대한 문제가 있습니다.
  • here Google에서 openid_id 필드를 반환하는 것과 비슷한 문제가있는 것 같습니다.
+0

을 upvoting로 도와주세요,이 정말 간단하지 발견하는 경우

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; } } 

을 한달이 넘는 검색 후에이 문제에 대한 해결책을 찾으십시오. – spadelives

+0

@spadelives 나는 당신이 마침내 Owin과 ASP.NET MVC를 사용하여 realm 매개 변수를 보내는 방법을 알아 냈다. 하지만 아직 이드의 신분을 모두 얻지 못하고 있습니다. 그렇습니까? – mikkark

+0

예, 실제로 두 ID를 모두 얻고 있지만, 불행히도, 동시에 아닙니다 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 추가 : 나 같은 당신이 우리는 또한 수 없었습니다이 문제 https://katanaproject.codeplex.com/workitem/359

+0

전적으로이 답변이 ASP.NET MVC에만 국한되는 것은 아닙니다. 우리의 앱은 일반 ASP.NET이지만 동일한 일반적인 아이디어가 여전히 적용되어야합니다. – mikkark

+0

그래, 그 코드 조각은 MVC에 spesific하지 않습니다. OWIN에 익숙하지 않아서 틀렸어. 필자는 피질의 코드를 사용하여 이전 ID를 실제로 얻을 수 있음을 확인할 수 있습니다. 이제는이 Owin 코드를 현재의 인증 메커니즘과 함께 ASP.NET (비 MVC) 및 "측면에서"작업하는 방법을 정확히 알고 싶습니다. 또한, 우리의 응용 프로그램은 .net 4.0이므로 Owin을 사용하려면 프레임 워크를 업그레이드해야합니다. – mikkark

+0

나는 이것을 일반 ASP.NET에서도 작동하도록 만들었다. 우리는 사물을 조금 엉망으로 만드는 타사 SAML 기반 인증 라이브러리를 사용합니다. 내가 그것을 제거한 후에 나는이 일을 얻었다.다른 서버에 두 개의 설치가 있고 그 중 하나가 SAML을 사용하고 다른 하나가 OAuth 및 SAML을 사용하지 않기 때문에 실제로 작동합니다. 아직도, 나는 그들이 적어도 지금은 작동하지 않는다는 것을 이해하기 위해 함께 일하게하고 싶다. – mikkark

관련 문제