AuthenticationProperties.RedirectUri не се предава на Google в Challenge()

В рамките на моето уеб приложение съм регистрирал Google като доставчик на еднократно влизане:

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions {
    ClientId = "8765.......apps.googleusercontent.com",
    ClientSecret = "Secret"
})

Приложението ми не позволява на потребителите да се регистрират/регистрират (вместо това акаунтите им се създават от администратор, но те могат по-късно да свържат акаунта си с Google).

В моя контролер „Вход с Google“ се опитвам да издам Challenge() за пренасочване към Google. Това може да не е правилният подход:

string redirectUri = "http://localhost:55262/SSO/Google/ProcessToken"; // actually created in code, but shown as string for clarity
AuthenticationProperties properties = new AuthenticationProperties();
properties.RedirectUri = Server.UrlEncode(redirectUri);
Context.GetOwinContext().Authentication.Challenge(properties, "Google");

Това правилно изпраща потребителя към Google, но след това Google представя Грешка: redirect_uri_mismatch, като казва, че:

URI адресът за пренасочване в заявката: http://localhost:55262/signin-google не съответства на регистриран URI за пренасочване.

Виждал съм тази грешка и преди, когато колекцията URI за връщане в контролния панел на Google не съдържа посочения redirect_uri.

Ако отстранявам грешки във VS2015, виждам, че свойството redirect_uri е зададено правилно в AuthenticationProperties, но изглежда, че OWIN/Katana не го предава на Google. Вместо това, когато натисна Google, return_uri е този по подразбиране, използван от OWIN/Katana. Този, който зададох, се игнорира.

Подробностите за заявката на Google изглежда потвърждават това:

scope=openid profile email
response_type=code
redirect_uri=http://localhost:55262/signin-google

Какво правя грешно тук, моля? Не трябва ли да използвам Challenge(), за да позволя на потребителите да свържат акаунта си за локално приложение с Google?


person EvilDr    schedule 13.11.2015    source източник
comment
Какво е GoogleOAuth2AuthenticationOptions? Жалко, че не е пълна извадка за OWIN-Katana с помощта на Google.   -  person Kiquenet    schedule 04.05.2016
comment
Това е обект от клас OWIN, който съдържа задължителните полета за Google OAuth2 удостоверяване. Използва се само за Google, естествено.   -  person EvilDr    schedule 04.05.2016


Отговори (2)


Забележете, че Open Authentication на OWIN има предварително дефинирани методи. С други думи, в localhost:port/signin-google, OWIN чака извикване на signin-google от външната услуга за удостоверяване (въпреки че не можете да намерите нейното изпълнение в проекта). signin-google е валиден и работещ път и аз предварително ви увещавам да не го променяте (поради избягване на писане на нова реализация като действие на контролера).

Имах подобен проблем. След като прекарах много уморителни дни, най-накрая разбрах, че проблемът идва от URL адреса на оригиналния потребител, който е ефективен при изпратения redirect_uri от OWIN. Ясно:

  • Ако въведете www.site.com redirect_uri е равно на www.site.com/signin-google
  • Ако въведете site.com redirect_uri е равно на site.com/signin-google

И Google ще върне redirect_uri_mismatch Грешка за един от горните случаи въз основа на въведени URL адреси за пренасочване в конзолата. Мисля, че вашият проблем също идва от тази реалност и решението е да зададете всички възможни URL адреси в конзолата.

person Amirhossein Mehrvarzi    schedule 16.11.2015

За предоставяне на допълнителна информация относно приетия отговор...

Добре е да игнорирате /signin-google

Оказва се, че /signin-google URI се управлява вътрешно от OWIN/Katana. Вие, като програмист, не трябва да се притеснявате от това, но наистина трябва да го добавите в конзолата за разработчици на Google като URI за оторизирано пренасочване.

В заявката на Google имайте предвид, че OWIN винаги предава URI за пренасочване към Google като /signin-google, независимо какъв потребителски URI сте задали в свойството AuthenticationProperties.RedirectUri. Въпреки че в началото това може да изглежда като грешка/проблем, има голямо предимство в това, че OWIN може да управлява всички обратни извиквания чрез един URI за обратно извикване. Вашият URI за обратно извикване също не е забравен (вижте по-долу)!.

И така, какво да кажем за вашия собствен URL адрес за пренасочване?

Е, това е мястото, където AuthenticationProperties() влиза в игра. Като посочите свой собствен URL адрес за обратно извикване, така...

AuthenticationProperties properties = new AuthenticationProperties { RedirectUri = "https://my.app.com/custom/callback/uri" };

...след като OWIN провери токена на Google и извлече необходимите подробности, потребителят се пренасочва към посочения от вас URL адрес.

Това беше мястото, където се обърквах, тъй като не разбирах какво да правя с /signin-google, когато всъщност не бяха предприети никакви действия. Това се отнася както за MVC, така и за уеб формуляри - не е нужно да се притеснявате какво се предава на Google. Въпреки това, ако използвате уеб формуляри или зададете правила за оторизация в web.config, ще ви трябва това, за да предотвратите повторното натискане на връщащите се потребители на страницата за регистриране:

<location path="signin-google">
    <system.web>
        <authorization>
            <allow users="*"/>
        </authorization>
    </system.web>
</location>

Ето целия код, от който се нуждаете, за да изпратите потребителя на Google и да върнете токена, съдържащ неговите подробности:

Изходяща

Изпратете потребителя до Google от контролер, събитие с щракване върху бутон, зареждане на страница, всичко (независимо от вашия ASP/хостинг стек):

// set the callback, for after OWIN finishes examining what comes back from Google
AuthenticationProperties properties = new AuthenticationProperties { RedirectUri = "https://www.myapp.com/some/callback/uri" };
// send the user to Google
Context.GetOwinContext().Authentication.Challenge(properties, "Google");
// Stop execution of the current page/method - the 401 forces OWIN to kick-in and do its thing
Response.StatusCode = 401;
Response.End();

Входящи

Потребителят се връща от Google след потвърждаване на самоличността му

Microsoft.AspNet.Identity.Owin.ExternalLoginInfo loginInfo = Context.GetOwinContext().Authentication.GetExternalLoginInfo();
person EvilDr    schedule 16.11.2015
comment
Response.StatusCode = 401; Response.End(); беше ключовата модификация. Благодаря ви, това отне известно време за проследяване. Реф.: stackoverflow.com/questions/47458095/ - person gb2d; 24.11.2017
comment
Това е пълно минно поле, нали :-/ - person EvilDr; 24.11.2017