Как решить проблему получения 401 несанкционированного доступа в ответ на попытку получить токен? - PullRequest
0 голосов
/ 09 января 2019

У меня есть Identity Server (использующий IdentityServer4), веб-API, который использует Identity Server для авторизации, и приложение Xamarin, которое использует Identity Server для входа в систему и аутентификации API.

Когда я запускаю все три части локально из Visual Studio, я могу войти в систему с помощью приложения Xamarin, получить токен и использовать этот токен для выполнения вызовов API. Однако, когда я публикую Identity Server на веб-сервере (в той же сети), он завершается неудачно в тот момент, когда он пытается получить токен. Таким образом, он показывает страницу входа в систему, кажется, что он принимает имя входа, но POST для получения токена завершается ошибкой с 401 несанкционированной ошибкой в ​​ответе.

Я также настроил Identity Server, чтобы разрешить Swagger подключаться для тестирования API, и это позволяет мне входить в систему (используя Implicit), используя Identity Server, установленный на веб-сервере.

Это метод, который выполняет POST в приложении Xamarin (в основном, скопировано из примера eShopOnContainers):

public async Task<TResult> PostAsync<TResult>(string uri, string data, string clientId, string clientSecret)
{
  HttpClient httpClient = CreateHttpClient(string.Empty);

  if (!string.IsNullOrWhiteSpace(clientId) && !string.IsNullOrWhiteSpace(clientSecret))
  {
      AddBasicAuthenticationHeader(httpClient, clientId, clientSecret);
  }

  var content = new StringContent(data);
  content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
  HttpResponseMessage response = await httpClient.PostAsync(uri, content);

  await HandleResponse(response);
  string serialized = await response.Content.ReadAsStringAsync();

  TResult result = await Task.Run(() =>
        JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));

  return result;
}

Вот метод вызова для получения токена:

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(Settings.Service.IdentityCallback), _codeVerifier);
    var token = await _requestProvider.PostAsync<UserToken>(
        Settings.Service.IdentityTokenEndpoint, data, Settings.Service.IdentityClientId, Settings.Service.IdentityClientSecret);
    return token;
}

URI - "http://myserver:5002/connect/token", а заголовки:

Accept: "application/json"
Authorization: "Basic SW5zdGVtLkFDSVMuTW9iaWxlOnNlY3JldA=="
ContentType: "application/x-www-form-urlencoded"

Журнал на веб-сервере дает мне это:

    info: IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator[0]
          Showing login: User is not authenticated
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 3.4723ms 302 
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 GET http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3D0dc5d79410db46739c798ce004ac89b8%26code_challenge%3DAuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c%26code_challenge_method%3DS256%26state%3D031db7b77c7249aebb6f7ae205dac016  
    info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
          Route matched with {action = "Login", controller = "Account"}. Executing action IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer)
    info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
          Executing action method IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer) with arguments (/connect/authorize/callback?client_id=Company.App.Mobile&client_secret=secret&response_type=code%20id_token&scope=openid%20profile%20app_api%20offline_access&redirect_uri=http%3A%2F%2Fmyserver%3A5002%2FAccount%2FRedirect&nonce=0dc5d79410db46739c798ce004ac89b8&code_challenge=AuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c&code_challenge_method=S256&state=031db7b77c7249aebb6f7ae205dac016) - Validation state: Valid
    info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
          Executed action method IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer), returned result Microsoft.AspNetCore.Mvc.ViewResult in 0.3611ms.
    info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[1]
          Executing ViewResult, running view Login.
    info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[4]
          Executed ViewResult - view Login executed in 1.7974ms.
    info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
          Executed action IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer) in 2.4715ms
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 3.1044ms 200 text/html; charset=utf-8
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 GET http://myserver:5002/css/site.css  
    info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
          The file /css/site.css was not modified
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 0.6236ms 304 text/css
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 GET http://myserver:5002/lib/bootstrap/js/bootstrap.js  
    info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
          The file /lib/bootstrap/js/bootstrap.js was not modified
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 0.3461ms 304 application/javascript
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 GET http://myserver:5002/lib/jquery/jquery.js  
    info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
          The file /lib/jquery/jquery.js was not modified
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 0.2798ms 304 application/javascript
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 GET http://myserver:5002/icon.png  
    info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
          The file /icon.png was not modified
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 0.2655ms 304 image/png
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 GET http://myserver:5002/lib/bootstrap/css/bootstrap.css  
    info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
          The file /lib/bootstrap/css/bootstrap.css was not modified
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 0.26ms 304 text/css
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 POST http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3D0dc5d79410db46739c798ce004ac89b8%26code_challenge%3DAuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c%26code_challenge_method%3DS256%26state%3D031db7b77c7249aebb6f7ae205dac016 application/x-www-form-urlencoded 712
    info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
          Route matched with {action = "Login", controller = "Account"}. Executing action IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer)
    info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
          Executing action method IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer) with arguments (IdentityServer4.Quickstart.UI.LoginInputModel, login) - Validation state: Valid
    info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
          AuthenticationScheme: idsrv signed in.
    info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
          Executed action method IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer), returned result Microsoft.AspNetCore.Mvc.ViewResult in 1.0902ms.
    info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[1]
          Executing ViewResult, running view Redirect.
    info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[4]
          Executed ViewResult - view Redirect executed in 10.0474ms.
    info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
          Executed action IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer) in 12.3805ms
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 13.1928ms 302 text/html; charset=utf-8
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 GET http://myserver:5002/connect/authorize/callback?client_id=Company.App.Mobile&client_secret=secret&response_type=code%20id_token&scope=openid%20profile%20app_api%20offline_access&redirect_uri=http%3A%2F%2Fmyserver%3A5002%2FAccount%2FRedirect&nonce=0dc5d79410db46739c798ce004ac89b8&code_challenge=AuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c&code_challenge_method=S256&state=031db7b77c7249aebb6f7ae205dac016  
    info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
          Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint for /connect/authorize/callback
    info: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint[0]
          ValidatedAuthorizeRequest
          {
            "ClientId": "Company.App.Mobile",
            "ClientName": "App Mobile",
            "RedirectUri": "http://myserver:5002/Account/Redirect",
            "AllowedRedirectUris": [
              "http://myserver:5002/Account/Redirect"
            ],
            "SubjectId": "eb194e4a-a2f7-482c-8c43-204567ebd591",
            "ResponseType": "code id_token",
            "ResponseMode": "fragment",
            "GrantType": "hybrid",
            "RequestedScopes": "openid profile app_api offline_access",
            "State": "031db7b77c7249aebb6f7ae205dac016",
            "Nonce": "0dc5d79410db46739c798ce004ac89b8",
            "SessionId": "0ed1a950919c3b368e1249ec74e35f2c",
            "Raw": {
              "client_id": "Company.App.Mobile",
              "client_secret": "secret",
              "response_type": "code id_token",
              "scope": "openid profile app_api offline_access",
              "redirect_uri": "http://myserver:5002/Account/Redirect",
              "nonce": "0dc5d79410db46739c798ce004ac89b8",
              "code_challenge": "AuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c",
              "code_challenge_method": "S256",
              "state": "031db7b77c7249aebb6f7ae205dac016"
            }
          }
    info: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint[0]
          Authorize endpoint response
          {
            "SubjectId": "eb194e4a-a2f7-482c-8c43-204567ebd591",
            "ClientId": "Company.App.Mobile",
            "RedirectUri": "http://myserver:5002/Account/Redirect",
            "State": "031db7b77c7249aebb6f7ae205dac016",
            "Scope": "openid profile app_api offline_access"
          }
    info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
          AuthenticationScheme: idsrv signed in.
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 40.3114ms 302 
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
          Request starting HTTP/1.1 GET http://myserver:5002/Account/Redirect  
    info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
          Request finished in 0.9519ms 404 

Адрес "http://myserver:5002/Account/Redirect" на самом деле не существует, потому что клиент является приложением Xamarin, поэтому я не думаю, что 404 в конце - это проблема. Похоже, в журнале нет ничего для вызова токена.

Вот клиентская конфигурация для Identity Server:

new Client
{
    ClientName = "ACIS Mobile",
    ClientId = "Instem.ACIS.Mobile",
    AllowedGrantTypes = GrantTypes.Hybrid,
    ClientSecrets =
    {
        new Secret("secret".Sha256())
    },
    RedirectUris = {$"{identityUri}/Account/Redirect"},
    RequireConsent = false,
    RequirePkce = true,
    PostLogoutRedirectUris = {$"{identityUri}/Account/Redirecting"},
    AllowedCorsOrigins = { "http://xamarinapp" },
    AllowedScopes = new List<string>
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,
        IdentityServerConstants.StandardScopes.OfflineAccess,
        "acis_api"
    },
    AllowOfflineAccess = true,
    AllowAccessTokensViaBrowser = true
},
new Client
{
    ClientName = "Swagger UI",
    ClientId="swaggerui",
    AllowedGrantTypes=GrantTypes.Implicit,
    AllowAccessTokensViaBrowser=true,
    RedirectUris = { $"{webApiUri}/oauth2-redirect.html" },
    PostLogoutRedirectUris={ $"{webApiUri}/" },
    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,
        "acis_api"
    }
}

Настройка запуска сервера идентификации довольно проста:

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc();

  services.AddIdentityServer()
    .AddInMemoryClients(Config.GetClients(Configuration))
    .AddInMemoryIdentityResources(Config.GetIdentityResources())
    .AddInMemoryApiResources(Config.GetApiResources())
    .AddTestUsers(Config.GetUsers())
    //.AddDeveloperSigningCredential();
    .AddSigningCredential("some certificate thumbprint", System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, NameType.Thumbprint);

  services.AddAuthentication()
  .AddMicrosoftAccount(options =>
  {
    options.ClientId = "someclientid";
    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    options.ClientSecret = "somesecret";
  });
}

  // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
    if (env.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();
    }

    app.UseIdentityServer();
    app.UseStaticFiles();
    app.UseMvcWithDefaultRoute();
}

В IIS я настроил его на анонимную и базовую аутентификацию.

Это в значительной степени новое для меня, и я добивался прогресса до этого момента, но я не вижу никакой причины, по которой он дает мне 401 Несанкционированную ошибку, и я даже не вижу ничего в каких-либо журналах, чтобы дать мне на что угодно.

Edit:

Я нашел файл журнала с дополнительной информацией:

2019-01-08 12:08:51 172.26.2.174 POST /Account/Login ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3Ddc06cb800d6f4f729df03a986ff2f165%26code_challenge%3DN343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo%26code_challenge_method%3DS256%26state%3D86f26cf6a5184d9a8263aac954711819 5002 - 172.16.190.147 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+WebView/3.0)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/64.0.3282.140+Safari/537.36+Edge/17.17134 http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3Ddc06cb800d6f4f729df03a986ff2f165%26code_challenge%3DN343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo%26code_challenge_method%3DS256%26state%3D86f26cf6a5184d9a8263aac954711819 302 0 0 156
2019-01-08 12:09:49 172.26.2.174 GET /connect/authorize/callback client_id=Company.App.Mobile&client_secret=secret&response_type=code%20id_token&scope=openid%20profile%20app_api%20offline_access&redirect_uri=http%3A%2F%2Fmyserver%3A5002%2FAccount%2FRedirect&nonce=dc06cb800d6f4f729df03a986ff2f165&code_challenge=N343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo&code_challenge_method=S256&state=86f26cf6a5184d9a8263aac954711819 5002 - 172.16.190.147 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+WebView/3.0)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/64.0.3282.140+Safari/537.36+Edge/17.17134 http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3Ddc06cb800d6f4f729df03a986ff2f165%26code_challenge%3DN343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo%26code_challenge_method%3DS256%26state%3D86f26cf6a5184d9a8263aac954711819 302 0 0 593
2019-01-08 12:10:33 172.26.2.174 POST /connect/token - 5002 Company.App.Mobile 172.16.190.147 - - 401 1 1326 50
2019-01-08 12:10:33 172.26.2.174 GET /Account/Redirect - 5002 - 172.16.190.147 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+WebView/3.0)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/64.0.3282.140+Safari/537.36+Edge/17.17134 http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3Ddc06cb800d6f4f729df03a986ff2f165%26code_challenge%3DN343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo%26code_challenge_method%3DS256%26state%3D86f26cf6a5184d9a8263aac954711819 404 0 0 15

Это линия соединения / токена с ошибкой 401.

1 Ответ

0 голосов
/ 10 января 2019

В IIS для Identity Server включена базовая аутентификация. Как только я это выключил, все работает нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...