Xamarin Mobile с IdentityServer 3

Я пытаюсь установить безопасное соединение для своего мобильного приложения, используя Identity Server 3 и Xamarin. У меня есть веб-приложение, которое отлично работает на сервере идентификации, но не может заставить его работать с мобильным телефоном. У меня есть запрос учетных данных, вход в систему и получение токена доступа. Однако, когда я пытаюсь сделать вызов с использованием токена, я все равно получаю HttpContext.User.Identity.IsAuthenticated как false, и вызов не удается.

Я создал новый клиент на сервере удостоверений для мобильного приложения, и он выглядит следующим образом:

new IdentityServer3.Core.Models.Client
{
  Enabled = true,
  ClientName = "MyMobile Mobile App",
  ClientId = "myMobile",
  ClientSecrets = { new Secret("myMobileSecret".Sha256()) },
  Flow = Flows.Hybrid,
  RedirectUris = new List<string>
  {
    …
  },
  PostLogoutRedirectUris = new List<string>
  {
    …
  },
  RequireConsent = false,
  AllowAccessToAllScopes = true,
  RequireSignOutPrompt = false
}

Мой код выглядит следующим образом:

var authorizeRequest = new AuthorizeRequest(GlobalSetting.Instance.IdentityEndpoint);

var dic = new Dictionary<string, string>();
dic.Add("client_id", GlobalSetting.Instance.ClientId);
dic.Add("client_secret", GlobalSetting.Instance.ClientSecret);
dic.Add("response_type", "code token");
dic.Add("scope", "openid profile roles");
dic.Add("redirect_uri", GlobalSetting.Instance.IdentityCallback);
dic.Add("nonce", Guid.NewGuid().ToString("N"));

_currentCSRFToken = Guid.NewGuid().ToString("N");
dic.Add("state", _currentCSRFToken);

var authorizeUri = authorizeRequest.Create(dic);           
LoginWebView.Source = authorizeUri;

На ответ...

private async Task NavigateAsync(string url)
{
  var unescapedUrl = System.Net.WebUtility.UrlDecode(url);

  if (unescapedUrl.StartsWith(GlobalSetting.Instance.IdentityCallback))
  {
      LoginWebView.IsVisible = false;

      var authResponse = new AuthorizeResponse(url);
      if (!string.IsNullOrWhiteSpace(authResponse.Code))
      {
          var userToken = await _identityService.GetTokenAsync(authResponse.Code);

          string accessToken = userToken.AccessToken;
          if (!string.IsNullOrWhiteSpace(accessToken))
          {
              Authorization.AccessToken = accessToken;
              Authorization.IdToken = authResponse.IdentityToken;

              Application.Current.MainPage = _homePage;
          }
      }
  }
  …
}

public async Task<UserToken> GetTokenAsync(string code)
{
  string data = string.Format("grant_type=authorization_code&code={0}&redirect_uri={1}&code_verifier={2}", code, WebUtility.UrlEncode(GlobalSetting.Instance.IdentityCallback), _codeVerifier);
  var token = await _requestProvider.PostAsync<UserToken> (GlobalSetting.Instance.TokenEndpoint, data, GlobalSetting.Instance.ClientId, GlobalSetting.Instance.ClientSecret);
  return token;
}

А потом, когда я звоню...

RestClient rest = new RestClient(GlobalSetting.DefaultBaseUrl);

var request = new RestRequest("Partner/GetMyItem", Method.POST);
request.AddParameter("detail", MyEnumValue.ToString());

//tried both of the following…
request.AddParameter("Authorization", string.Format("Bearer {0}", Authorization.AccessToken), ParameterType.HttpHeader);
rest.AddDefaultHeader("Authorization", string.Format("Bearer {0}", Authorization.AccessToken));

IRestResponse res = rest.Post(request);

Функция...

[HttpPost]
[ValidateInput(false)]
[AuthAttribute(Roles = …)]
[HandleForbidden]
public string GetMyItem(MyEnum detail)

В журнале идентификации сервера у меня есть следующее...

2018-07-23 14:03:11.508 +00:00 [Information] Start authorize request
2018-07-23 14:03:11.508 +00:00 [Information] Start authorize request protocol validation
2018-07-23 14:03:11.508 +00:00 [Information] "Authorize request validation success"
 "{
  \"ClientId\": \"myMobile\",
  \"ClientName\": \"myMobile App\",
  \"RedirectUri\": \"https://localhost:44000/\",
  \"AllowedRedirectUris\": [
    \"https://localhost:44000/\",
      ...
  ],
  \"SubjectId\": \"unknown\",
  \"ResponseType\": \"code token\",
  \"ResponseMode\": \"fragment\",
  \"Flow\": \"Hybrid\",
  \"RequestedScopes\": \"openid profile roles\",
  \"State\": \"a971d692ae8f424493966023f5934b70\",
  \"Nonce\": \"ec42d50463cc418dacbd04f1c43873d0\",
  \"Raw\": {
    \"client_id\": \"myMobile\",
    \"client_secret\": \"myMobileSecret\",
    \"response_type\": \"code token\",
    \"scope\": \"openid profile roles\",
    \"redirect_uri\": \"https://localhost:44000/\",
    \"nonce\": \"ec42d50463cc418dacbd04f1c43873d0\",
    \"state\": \"a971d692ae8f424493966023f5934b70\"
  }
}"
2018-07-23 14:03:11.524 +00:00 [Information] User is not authenticated. Redirecting to login.
2018-07-23 14:03:11.524 +00:00 [Information] End authorize request
2018-07-23 14:03:11.524 +00:00 [Information] Redirecting to login page
2018-07-23 14:03:11.524 +00:00 [Debug] Protecting message: "{\"ReturnUrl\":\"https://....net/identity/connect/authorize?client_id=myMobile&client_secret=myMobileSecret&response_type=code%20token&scope=openid%20profile%20roles&redirect_uri=https%3A%2F%2Flocalhost%3A44000%    2F&nonce=ec42d50463cc418dacbd04f1c43873d0&state=a971d692ae8f424493966023f5934b70\",\"ClientId\":\"myMobile\",\"AcrValues\":[],\"Created\":636679513915083066}"
2018-07-23 14:03:11.570 +00:00 [Information] Login page requested
2018-07-23 14:03:11.570 +00:00 [Debug] signin message passed to login: "{
  \"ReturnUrl\": \"https://...net/identity/connect/authorize?client_id=myMobile&client_secret=myMobileSecret&response_type=code%20token&scope=openid%20profile%20roles&redirect_uri=https%3A%2F%2Flocalhost%3A44000%    2F&nonce=ec42d50463cc418dacbd04f1c43873d0&state=a971d692ae8f424493966023f5934b70\",
  \"ClientId\": \"myMobile\",
  \"IdP\": null,
  \"Tenant\": null,
  \"LoginHint\": null,
  \"DisplayMode\": null,
  \"UiLocales\": null,
  \"AcrValues\": [],
  \"Created\": 636679513915083066
}"
2018-07-23 14:03:11.570 +00:00 [Information] rendering login page
2018-07-23 14:03:12.007 +00:00 [Information] CSP Report endpoint requested
2018-07-23 14:03:12.007 +00:00 [Information] CSP Report data: "{\"csp-report\":{\"document-uri\":\"https://...net/identity/login?signin=df9bdfc781a634b806ecc6555e9989ca\",\"referrer\":\"\",\"blocked-uri\":\"\",\"violated-directive\":\"script-src 'self'\",\"original-policy\":\"default-src 'self'; script-src 'self' ;     style-src 'self' 'unsafe-inline' style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; img-src *; font-src font-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; report-uri https://devs3server.azurewebsites.net/identity/csp/report\",\"effective-directive\":\"script-src\",\"status-code\":200,\"source-    file\":\"https://devs3server.azurewebsites.net/identity/login?signin=df9bdfc781a634b806ecc6555f9989ca\"}}"
2018-07-23 14:03:12.007 +00:00 [Information] Rendering 204
2018-07-23 14:03:26.772 +00:00 [Information] Login page submitted
2018-07-23 14:03:26.803 +00:00 [Information] Login credentials successfully validated by user service
2018-07-23 14:03:26.803 +00:00 [Information] Calling PostAuthenticateAsync on the user service
2018-07-23 14:03:26.819 +00:00 [Information] issuing primary signin cookie
2018-07-23 14:03:26.819 +00:00 [Information] redirecting to: https://....net/identity/connect/authorize?client_id=myMobile&client_secret=myMobileSecret&response_type=code token&scope=openid profile roles&redirect_uri=https:%2F%2Flocalhost:44000%    2F&nonce=ec42d50463cc418dacbd04f1c43873d0&state=a971d692ae8f424493966023f5934b70
2018-07-23 14:03:26.866 +00:00 [Information] Start authorize request
2018-07-23 14:03:26.881 +00:00 [Information] Start authorize request protocol validation
2018-07-23 14:03:26.881 +00:00 [Information] "Authorize request validation success"
 "{
  \"ClientId\": \"myMobile\",
  \"ClientName\": \"my Mobile App\",
  \"RedirectUri\": \"https://localhost:44000/\",
  \"AllowedRedirectUris\": [
    \"https://localhost:44000/\",
    ...
  ],
  \"SubjectId\": \"2957b247-43ed-4aea-b5b4-c0a76a613942\",
  \"ResponseType\": \"code token\",
  \"ResponseMode\": \"fragment\",
  \"Flow\": \"Hybrid\",
  \"RequestedScopes\": \"openid profile roles\",
  \"State\": \"a971d692ae8f424493966023f5934b70\",
  \"Nonce\": \"ec42d50463cc418dacbd04f1c43873d0\",
  \"SessionId\": \"3e67194d4c5ba7d1c8586948377f9fe7\",
  \"Raw\": {
    \"client_id\": \"myMobile\",
    \"client_secret\": \"myMobileSecret\",
    \"response_type\": \"code token\",
    \"scope\": \"openid profile roles\",
    \"redirect_uri\": \"https://localhost:44000/\",
    \"nonce\": \"ec42d50463cc418dacbd04f1c43873d0\",
    \"state\": \"a971d692ae8f424493966023f5934b70\"
  }
}"
2018-07-23 14:03:26.881 +00:00 [Information] Creating Hybrid Flow response.
2018-07-23 14:03:26.881 +00:00 [Information] Creating Implicit Flow response.
2018-07-23 14:03:26.881 +00:00 [Debug] Creating access token
2018-07-23 14:03:26.881 +00:00 [Debug] Creating JWT access token
2018-07-23 14:03:26.912 +00:00 [Debug] Adding client "myMobile" to client list cookie for subject "2957b247-43ed-4aea-b5b4-c0a76a613942"
2018-07-23 14:03:26.912 +00:00 [Information] End authorize request
2018-07-23 14:03:26.912 +00:00 [Information] Redirecting to: https://localhost:44000/
2018-07-23 14:03:28.950 +00:00 [Information] Start token request
2018-07-23 14:03:28.950 +00:00 [Debug] Start client validation
2018-07-23 14:03:28.950 +00:00 [Debug] Start parsing Basic Authentication secret
2018-07-23 14:03:28.950 +00:00 [Debug] Parser found secret: "BasicAuthenticationSecretParser"
2018-07-23 14:03:28.950 +00:00 [Information] Secret id found: "myMobile"
2018-07-23 14:03:28.950 +00:00 [Debug] Secret validator success: "HashedSharedSecretValidator"
2018-07-23 14:03:28.950 +00:00 [Information] Client validation success
2018-07-23 14:03:28.950 +00:00 [Information] Start token request validation
2018-07-23 14:03:28.950 +00:00 [Information] Start validation of authorization code token request
2018-07-23 14:03:28.950 +00:00 [Information] Validation of authorization code token request success
2018-07-23 14:03:28.950 +00:00 [Information] Token request validation success
 {
  "ClientId": "myMobile",
  "ClientName": "my Mobile App",
  "GrantType": "authorization_code",
  "AuthorizationCode": "dc7be1793efe246ca817d7d35298b355",
  "Raw": {
    "grant_type": "authorization_code",
    "code": "dc7be1793efe246ca817d7d35298b355",
    "redirect_uri": "https://localhost:44000/",
    "code_verifier": ""
  }
}

Может ли кто-нибудь помочь мне заставить мобильное приложение xamarin работать с сервером идентификации 3 для вызова apis?

1 ответ

Ваш API должен быть зарегистрирован как клиент на вашем Identity Server в качестве области ресурсов.

Затем вам нужно подключить аутентификацию канала-носителя в промежуточном программном обеспечении вашего API с помощью UseBearerTokenAuthentication, Это необходимо для того, чтобы API мог авторизовать входящие запросы, использующие Authorization заголовок со схемой на предъявителя.

Наконец, ваше мобильное приложение должно запрашивать эту область при отправке запроса на аутентификацию. Однако вам также необходимо убедиться, что ваш клиент мобильного приложения зарегистрирован в этой области на Identity Server.

Другие вопросы по тегам