Доступ к API, защищенному с помощью Azure AD, из веб-клиента с помощью IdentityServer4 - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть API, защищенный Azure AD, к которому я пытаюсь получить доступ из приложения MVC.Это приложение MVC использует IdentityServer4 в качестве IDP, а Azure AD настроен в качестве внешнего поставщика.Я не могу вызвать API с токеном доступа, полученным из Azure AD.

Вот мои настройки.Грубый эскиз, чтобы показать, что я делаю enter image description here

Конфигурация Azure

  1. API настроен как приложение в Azure AD (для простоты, скажем, appId: API)
  2. IdentityServer настроен как приложение с идентификатором токена и включенным токеном доступа.Добавлены разрешения для API (скажем, appId: IDSRV)

IdentityServer4 Configuration:

  1. Startup.cs - ConfigureServices

    services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())
            .AddTestUsers(Config.GetUsers());
    
    services.AddAuthentication()
        .AddOpenIdConnect("oidc", "Azure AD", options =>
        {
            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
            options.SignOutScheme = IdentityServerConstants.SignoutScheme;
    
            options.Authority = "https://login.microsoftonline.com/tenant.onmicrosoft.com/";
            options.ClientId = "IDSRV";
            options.Resource = "API"; //Identity server uses scopes but Azure AD expects this as a Resource. Not sure if this is the right way
            options.ClientSecret = "secret from azure";
    
            options.ResponseType = "code id_token";
            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name",
                RoleClaimType = "role"
            };
        });
    
  2. Я использую в памяти клиентов для тестирования

    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        {
            new Client
            {
                ClientId = "mvc",
                ClientName = "MVC Client",
                ClientSecrets =
                {
                    new Secret("secret".Sha256())
                },
                AllowedGrantTypes = GrantTypes.Hybrid,
                RedirectUris = { "http://localhost:49341/signin-oidc" },
                PostLogoutRedirectUris = { "http://localhost:49341/signout-callback-oidc" },
                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "API" //assume this is the appId from Azure
                }
            }
        };
    }
    
  3. Конфигурация ресурсов API: я думаю, это используется только на экране согласия

    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource("API","Test API")
        };
    }
    

Конфигурация веб-клиента: (Это клиент для Identiserver4 и ему необходим доступ к API)

  1. Startup.cs - ConfigureServices

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie("Cookies")
    .AddOpenIdConnect("oidc", options =>
    {
        options.SignInScheme = "Cookies";
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;
    
        options.ClientId = "mvc";
        options.ClientSecret = "secret";
    
        options.SaveTokens = true;
        options.ResponseType = "code id_token";
    
        options.Scope.Clear();
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("API");
    
        options.GetClaimsFromUserInfoEndpoint = true;
        options.SaveTokens = true;
    
        options.Resource = "b03d4318-278d-40fc-b6b3-3cf47a0e6f4d";//I guess this is actually irrelevant.
       });
    

При аутентификации нет ошибок, но я получаю несанкционированную ошибку, если пытаюсь получить доступ к API с полученным доступом.

Мне удалось настроить другой тестовый клиент напрямую с помощью Azure Ad и получить доступAPI, использующий полученный токен.

Теперь у меня есть два вопроса:

  1. Что-то не так с этой конфигурацией?
  2. Как динамически добавить Resource / Scopeот клиента к исходящему запросу Azure в IdentitySerвер?
...