如何使用安全声明代表AAD用户调用Web API?

时间:2019-06-02 14:49:14

标签: c# azure authorization identity claims

因此,为了让您大致了解我要实现的目标,我有一个Web应用程序 使用AAD身份验证,因此用户需要登录到Microsoft组织帐户 为了使用在Web应用程序(针对.NET Core)中实现的大多数控制器。 Visual Studio提供了用于此类Web应用程序设置的模板。这个 模板项目似乎以“ ClaimsIdentity”(System.Security.Claims.ClaimsIdentity)的形式获取用户的身份,到目前为止, 因为用户已通过AAD身份验证。 我也有一个.NET Core Web API解决方案,该Web应用程序需要代表 登录用户。因此,我有一个Web应用程序,该应用程序将用户登录到AAD,然后是Web API( Web应用程序调用),其控制器端点需要AAD身份验证请求。 为此,我的理解是Web应用程序需要包含以下已登录身份: Microsoft(在本例中为安全提供程序)随其一起提供了 要求它向API发送。然后,该API将能够查看用户声明并采取相应的措施。

问题在这里。作为标题,我认为我需要提供Microsoft发送的访问令牌 到网络应用程序。.但是我找不到此令牌。我可以从User或User.Identity中提取的只是声明。怎么样 我可以代表这些声明调用单独的API吗?我是否需要完全忽略模板 微软提供的并且只是调用/ token端点?我只想以正确的方式做到这一点:)

这是Web应用程序Startup类中的ConfigureServices方法:

public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options => Configuration.Bind("AzureAd", options));

        services.AddMvc(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

在这里,我要代表登录的AAD调用外部Web API,以获取 所需数据:

public IActionResult Index()
    {
        var user = User.Identity as ClaimsIdentity;

        var request = (HttpWebRequest)WebRequest.Create("http://localhost:4110/data");
        request.Headers["Authorization"] = "bearer " + getAccessToken_using_user;

        var response = (HttpWebResponse)request.GetResponse();

        var dataString = new StreamReader(response.GetResponseStream()).ReadToEnd();

        return View();
}

当然,我的意图是将“ getAccessToken_using_user”替换为Microsoft应该为其提供Web应用程序的访问令牌,如其diagram所示。

1 个答案:

答案 0 :(得分:0)

您可以使用MSAL获取下游API的访问令牌。

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/on-behalf-of#practical-usage-of-obo-in-an-aspnet--aspnet-core-application

这是代表流程的完整示例:

https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/tree/master/2.%20Web%20API%20now%20calls%20Microsoft%20Graph

public static IServiceCollection AddProtectedApiCallsWebApis(this IServiceCollection services, IConfiguration configuration, IEnumerable<string> scopes)
{
 ...
 services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
 {
  options.Events.OnTokenValidated = async context =>
  {
   var tokenAcquisition = context.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>();
   context.Success();

   // Adds the token to the cache, and also handles the incremental consent and claim challenges
   tokenAcquisition.AddAccountToCacheFromJwt(context, scopes);
   await Task.FromResult(0);
  };
 });
 return services;
}
private async Task GetTodoList(bool isAppStarting)
{
 ...
 //
 // Get an access token to call the To Do service.
 //
 AuthenticationResult result = null;
 try
 {
  result = await _app.AcquireTokenSilent(Scopes, accounts.FirstOrDefault())
                     .ExecuteAsync()
                     .ConfigureAwait(false);
 }
...

// Once the token has been returned by MSAL, add it to the http authorization header, before making the call to access the To Do list service.
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

// Call the To Do list service.
HttpResponseMessage response = await _httpClient.GetAsync(TodoListBaseAddress + "/api/todolist");
...
}