Piszę klienta SSO do AAD w C#. Używam bibliotek Microsoftu (Microsoft.Owin). Całość czasem działa, a czasem nie, bo dane zwracane przez serwer czasem przychodzą puste (User.Identity as ClaimsIdentity
nie jest nullem, ale pole Claims jest puste). Po stronie Azure do logów "Sign-ins" leci wtedy błąd
Sign-in error code: 50058
Failure reason: The application tried to perform a silent sign in and the user could not be silently signed in. The application needs to start an interactive flow giving users an option to sign in.
Przegrzebałem pół internetu, znalazłem na https://docs.microsoft.com/en-us/answers/questions/3586/enterprise-app-oauth2-sso-gets-invalid-session-key.html, że do url'a, do którego przekierowywana jest przeglądarka na strony MS celem zalogowania się, należy dodać parametr prompt=select_account
. To po to, żeby przeglądarka wyświetliła stronę wyboru konta, na które klient chce się zalogować. Tu się zaczyna problem. Nie mam pojęcia, jak to zrobić. W bibliotekach Owin są obecne klasy zawierające częściowo to, czego potrzebuję (OpenIdConnectParameterNames.Prompt
oraz OpenIdConnectPrompt.SelectAccount
), ale nie mam pojęcia jak tego użyć. Grzebanie w internecie nie pomogło, dokumentacja MS jest tak słaba, że równie dobrze mogłoby jej nie być, a jedyny znaleziony przykład używający OpenIdConnectParameterNames
działa w oparciu o handler AuthorizationCodeReceived
, ale my nie używamy Authorization Code, więc handler nawet nie jest wywoływany.
Jak tego użyć? Jak zalogować się do aplikacji C# tak, aby przejść przez stronę wyboru konta użytkownika, a potem dostać jego email, o ile ma go skonfigurowanego? W prawidłowo wołanej konfiguracji public void Configuration(IAppBuilder app)
ustawiam sobie Scope = $"{OpenIdConnectScope.OpenIdProfile} {OpenIdConnectScope.Email} {OpenIdConnectScope.OpenId}"
, a więc żądam emaila, tylko mail albo przychodzi w polu email, albo przychodzi w polu preferred_name, albo nie przychodzi w niczym, bo claims jest puste.