IT Share you

OWIN의 GetExternalLoginInfoAsync 항상 null 반환

shareyou 2020. 11. 9. 21:37
반응형

OWIN의 GetExternalLoginInfoAsync 항상 null 반환


새 MVC5 웹 응용 프로그램을 만들었으며 Google 또는 Facebook으로 로그인하려고하면의 ExternalLoginCallback작업 AccountController이 호출되지만 GetExternalLoginInfoAsync()항상 null을 반환합니다.

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
    return RedirectToAction("Login");
}

항상 null이기 때문에 로그인 페이지로 다시 리디렉션되고 프로세스가 다시 시작됩니다. 이 문제를 어떻게 해결할 수 있습니까?


OWIN Google 로그인이 표준 Visual Studio 2013, ASP.Net MVC5 사이트에서 제대로 작동하도록하려면 다음을 수행해야합니다.

  1. https://console.developers.google.com/project 에서 Google OpenId 계정을 설정합니다.

  2. 거기에서 콜백 URL을로 설정합니다 blah/signin-google. 수행 할 필요 가없는 작업
    에 대한 중요 참고 사항 :

    • Google에서 다시 리디렉션하기 위해 HTTPS를 사용할 필요는 없습니다. 일반 http : // localhost로 다시 리디렉션 할 수도 있습니다. 문제 없습니다.

    • 리디렉션 URL에 대해 아무것도 설정할 필요가 없습니다. Web.Config의 경로, 컨트롤러 작업 또는 특수 권한이 ​​없습니다. 리디렉션 URL은 항상 / signin-google이며 OWIN이이를 자동으로 처리합니다.

예를 들어 사이트가 me.com 인 경우 Google 개발자 콘솔에 다음 3 개의 콜백 URL이있을 수 있습니다.

http://localhost:53859/signin-google
http://test.me.com/signin-google
https://me.com/signin-google

VS가 프로젝트에 제공 한 포트 번호를 포함하는 첫 번째 것입니다.

  1. Google+ API를 사용합니다 . 이것은 숨겨진 문제 중 하나이며 여기에있는 문제의 근본 원인입니다. 이렇게하지 않으면 Request to /account/ExternalLoginCallbackinclude 를 놓치기 쉽습니다. &error=access_denied이는 Google이 거부하기 때문입니다. 사용자의 Google+ 기본 프로필에 대한 권한 요청 OWIN 나는 이것이 누구의 잘못인지, 구글인지 마이크로 소프트인지 알 수 없다.

Developers Console에서 Google+ API를 사용하려면 왼쪽의 API를 클릭하고 Google+를 찾은 다음 클릭하고 사용을 누르세요. 네, 정말 그렇게해야합니다. 당신이 그렇게하지 않으면 당신은 물에 빠진 것입니다.

  1. Google이 Developers Console에서 제공 한 ClientId 및 ClientSecret을 Startup.Auth에 추가하되 프로세스의 코드를 개선하여 OAuth2를 명시 적으로 사용하고 사용자의 이메일 주소를 명시 적으로 요청합니다.

    var google = new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "123abc.apps.googleusercontent.com",
        ClientSecret = "456xyz",
        Provider = new GoogleOAuth2AuthenticationProvider()
    };
    google.Scope.Add("email");
    app.UseGoogleAuthentication(google);
    

그게 다야. 드디어 작동했습니다.

한 번 더 반복하고 싶습니다. 이에 대한 많은 답변과 OWIN / Google이 작동하지 않는 문제와 같은 문제가 있으며 거의 ​​모두 현재 VS2013 / MVC5 / OWIN 템플릿에 대해 잘못되었습니다.
Web.Config를 전혀 수정할 필요가 없습니다.
특별한 경로를 만들 필요가 없습니다. 다른 위치
를 가리 키 /signin-google거나 다른 콜백 URL을 사용해서는 안되며 , OWIN / Google 프로세스에서 필요한 단계와 별개이므로 /account/externallogincallback또는에 직접 연결해서는 안됩니다 .externalloginconfirmation/signin-google


좋아요, 왜 null인지 알아 냈습니다. Google 콘솔에서 Google + API를 활성화해야합니다. 또한 비밀 키를 코드에 붙여 넣은 후 끝에 공백과 연결되지 않았는지 확인하십시오. 정상적인 오류를 반환 할 수없는 이유는 무엇입니까? 모르겠어요.


Nuget 패키지 Microsoft.Owin.Security.Facebook 버전 3.0.1이 더 이상 Facebook 로그인에서 작동하지 않는 것 같습니다.

이 패키지를 시험판 3.1.0 버전으로 업데이트하면 다음을 사용할 수 있습니다.

설치 패키지 Microsoft.Owin.Security.Facebook -Pre


다른 사람들이 올바르게 언급했듯이 대부분의 경우 Google+ API에 대한 권한이 없기 때문에 Google API Manager에서 Google+ API에 대한 프로젝트 권한을 얻는 방법은 다음과 같습니다.

1 단계. 상단 콤보 박스에서 You Project를 선택하고 Dashboard> Enable API로 이동합니다.여기에 이미지 설명 입력

2 단계 : Google plus를 검색하고 선택합니다.여기에 이미지 설명 입력

3 단계 : 활성화하십시오!여기에 이미지 설명 입력

해당 프로젝트의 대시 보드로 돌아 가면 하단에서 해당 프로젝트에 대해 활성화 된 API 목록을 볼 수 있습니다. 여기에 이미지 설명 입력


나는 그것이 어리 석다는 것을 알고 있지만 오랜 노력 끝에 IIS를 다시 시작하면 문제가 해결되었습니다.


이것은 내 문제를 해결했습니다.

Google+ API를 활성화합니다. 이것은 문제이며 여기에있는 문제의 근본 원인입니다. 이렇게하지 않으면 요청에를 /account/ExternalLoginCallback포함 하는 것을 놓치기 쉽습니다. &error=access_denied이는 Google이 OWIN이 사용자를 위해 만든 권한 요청을 거부했기 때문입니다. Google+ 기본 프로필. 나는 이것이 누구의 잘못인지, 구글인지 마이크로 소프트인지 알 수 없다.

Developers Console에서 Google+ API를 사용하려면 왼쪽의 API를 클릭하고 Google+를 찾은 다음 클릭하고 사용을 누르세요.


응용 프로그램의 모든 너깃 패키지를 간단히 업데이트하여 작동하도록했습니다.


나는 그것을 작동시키기 위해 다음을 수행했습니다.

개발자 포털에 로그온하고 응용 프로그램을 찾은 후 다음을 수행합니다.

앱 세부 정보> 앱 중심 목록 플랫폼> 웹 사이트에 대해 예 선택


나는 오늘이 문제에 직면했고 공급자를 할당 한 후에 원격 쿠키를 정의한 것으로 밝혀졌습니다.

당신이 배치하는지 확인하십시오 ...

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

전에...

app.UseFacebookAuthentication(
                   appId: "",
                   appSecret: "");

Web Api에서이 문제를 겪고 계신 분들을 위해. 다른 솔루션은 AuthenticationManager.GetExternalLoginInfoAsync();Google 플러스 API가 활성화되어 있어도 항상 null을 반환하지 않습니다 .

이 사용자 정의 함수를 사용하여 로그인 정보를 얻으십시오. 분명히 Microsoft는 웹 API를 통해 요청할 때 GetExternalLoginInfoAsync에 대한 버그가 있습니다.

private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer()
        {
            ExternalLoginInfo loginInfo = null;

            var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);

            if (result != null && result.Identity != null)
            {
                var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
                if (idClaim != null)
                {
                    loginInfo = new ExternalLoginInfo()
                    {
                        DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""),
                        Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value)
                    };
                }
            }
            return loginInfo;
        }

Although the answers above are all good, in my instance none of these worked - I'd checked and double checked the Google settings and agree with Chris Moschini that there's a lot of misleading info.

For me it was a 'doh moment when I realised that my Out of Process state service was not started! No errors (as a login was the first thing I was attempting after a reboot where the state service is set to manual start-up on the machine) just a Null from GetExternalLoginInfoAsync

Hope this helps someone else out.


After much searching and head scratching as well as following numerous red herring answers here on Stackoverflow I eventually went through all my options on my Google dev console and discovered a little blue [Enable] button on the Google+API overview page. I clicked this and hey presto it worked. Forget all the baloney you read about callback url and route configs, OWIN overrides the google default /signin-google redirect uri in any case and sends you back to ExternalLoginCallback. Just stick with the default implementation all will be good so long as you enable your Google+API.


I wanted to contribute to this one also. I just recently got this working. I had the problem with the GetExternalLoginInfoAsync returning null but only in production.

After a lot of searching I finally found my answer it was simply a problem with my database. In production I had set the wrong connection string so it would not connect properly but it was basically silent about it. The only thing that happened was GetExternallLoginInfoAsync returned null. So check you database connection string if this happens!

Also on a sidenote, the only thing that was needed to get this working was:

  • Set up a project in the Google console
  • Enable Google+ API
  • Copy your client id and client secret to the Startup.Auth.cs file.

You do not have to enable HTTPS, you do not have to create custom routes. But make sure your database is working properly!


It is true that you are going to need the Google plus Enabled. The big thing for me was the project URL. Open the properties window (View -> Properties Window) in VS and then right click the project and select properties. In small properties window copy your SSL URL, and then in the larger properties window select the Web tab and paste that URL in the Project URL.

Fixed the issue for me.

See in greater detail: https://docs.microsoft.com/en-us/aspnet/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on


For me I was migrating and old but working .NET 4.6.1 MVC website to core 1.1. Work stopped before I could get it working, when I picked it back up, I was then migrating to 2.x.

My problem was that the callback from Google was met with a 404 from my site. I thought it was supposed to hit AccountController.ExternalLoginCallback so I added a [Route(...)] to it and sure enough, Google's callback hit the action.

This then hit the null returned in this line (what kind of maniac returns a null?)

var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();

I reverse engineered it to find under the hood its ultimately getting the handler for ExternalScheme which for my was the cookies handler!

It all seemed wrong and I felt somehow that the middleware was supposed to just intercept the callback URI so I removed my [Route(...)] and the 404 problem came back.

I then found that I need to add this during startup.

applicationBuilder.UseAuthentication();

This solves the 404 but gives another issue.

No authenticationScheme was specified, and there was no DefaultSignInScheme found.

By adding a default scheme here, I resolve the error above.

serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
    .AddGoogle(googleOptions => Configuration.Bind("OAuth2:Providers:Google", googleOptions))
    .AddExternalCookie();

Now AccountController.ExternalLoginCallback is invoked again by some magic but I am back to the null return value.

I added this code above the offending line, which is essentially what is happening under the hood (looking at Microsoft's code on GitHub). Interestingly, h is of type CookieAuthenticationHandler and a has all my claims and information from Google inside!

var authHandler = this.HttpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
var h = await authHandler.GetHandlerAsync(this.HttpContext, IdentityConstants.ExternalScheme);
var a = await h.AuthenticateAsync();

var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();

Digging into GitHub and copy pasting internal code its running into my controller, I can see that it's failing to find ClaimTypes.NameIdentifier in my claims, this is the ProviderKey used later.

Hmm....

Concerned I was using old 1.x AccountController code with newer 2.x identity bits I did find some samples that still use this stuff, and some samples that use Razor Pages for it all, too. I'll continue with what I have.

So I'm next going to investigate mapping additional Google user JSON payload items into the claims. I think if my Google account ID (numeric, I guess) was mapped then everything would work.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=aspnetcore-2.2

Final Fix

I finally resolved the issue by adding a "claim action" to pull my Google identifier out of the JSON coming back from Google!

serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
    .AddGoogle(googleOptions =>
    {
        Configuration.Bind("OAuth2:Providers:Google", googleOptions);

        googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
    })
    .AddExternalCookie();

The sub field contains what eventually ends up in the nameidentifier claim and then into the ProviderKey that the AccountController wants.


다른 모든 답변으로는이 문제가 해결되지 않았으므로 동일한 보트에있는 경우 등록 컨트롤러 작업에 RequireHttps 속성이 있는지 확인하십시오.

    // GET: /Account/LoginRegister
    [AllowAnonymous]
    [RequireHttps]
    public ActionResult LoginRegister()
    {
        return View(new RegisterLoginViewModel());
    }

참고 URL : https://stackoverflow.com/questions/19775321/owins-getexternallogininfoasync-always-returns-null

반응형