我有一个使用Azure AD保护的web api应用程序(http://localhost:54540),如下所示,
现在我尝试使用OpenIdConnect
从常规MVC应用程序访问web api,这里是MVC的startup
类,
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
private static string authority = aadInstance + tenantId;
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri
});
}
}
现在,我正在尝试将web api访问到MVC控制器之一,如下所示,
[Authorize]
public class HomeController : Controller
{
public string AccessToken
{
get
{
//var claim = Context.User?.FindFirst("access_token");
//if (claim == null)
//{
// throw new InvalidOperationException();
//}
//return claim.Value;
}
}
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
using (var client = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:54540/api/message");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
var response = await client.SendAsync(request, cancellationToken);
response.EnsureSuccessStatusCode();
return View();
}
}
}
问题 - 获取AccessToken
需要哪些代码?谢谢!
答案 0 :(得分:1)
根据您的说明,您在Azure Web App上托管的WebAPI应用程序使用App Service Authentication / Authorization(EasyAuth),而无需在WebAPI应用程序中添加相关的身份验证中间件(例如Microsoft.Owin.Security.ActiveDirectory)。
要使用OpenIdConnect从MVC Web应用程序访问WebAPI,您可以按照以下方法操作:
对于AAD v1.0 app ,您可以在Azure门户上为MVC应用程序创建AAD应用程序,并设置访问WebAPI AAD应用程序所需的权限。然后,您可以按照juunas提供的教程添加OnAuthorizationCodeReceived
方法以通过ADAL检索令牌并缓存检索到的令牌,然后您可以使用authContext.AcquireTokenSilentAsync
在后续请求中获取访问令牌而无需要求用户凭证。
private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
{
var code = context.Code;
ClientCredential credential = new ClientCredential(clientId, appKey);
string userObjectID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));
// If you create the redirectUri this way, it will contain a trailing slash.
// Make sure you've registered the same exact Uri in the Azure Portal (including the slash).
Uri uri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, uri, credential, "<resource, you could specify it to the AAD app ClientId for your WebAPI application>");
}
注意:对于resource
中的AcquireTokenByAuthorizationCodeAsync
参数,您可以将其设置为WebAPI应用程序的AAD应用程序ClientId,而不是github中的graphResourceId
样品。如果在调用authContext.AcquireTokenSilentAsync
时tokenCache中没有有效令牌,则可能会遇到以下错误:
对于AAD v2.0应用,您需要在App Registration Portal注册应用。我已经检查过EasyAuth可以与v2.0应用程序配合使用,您可以使用Azure Portal上v2.0应用程序的clientId,clientSecret来配置AAD身份验证。对于此方法,在使用OpenIdConnect时,您需要MSAL使用ConfidentialClientApplication.AcquireTokenByAuthorizationCodeAsync
获取令牌并在后续请求中使用ConfidentialClientApplication.AcquireTokenSilentAsync
。您可以针对OpenIdConnect相关代码示例关注here,关于AcquireTokenSilentAsync
关注SampleAuthProvider。
此外,如果您在没有用户交互的情况下处理Daemon or Server Application to Web API,则可以使用OAuth 2.0客户端凭据授权流并提供clientId和clientSecret以通过使用MSAL for v2.0 app或ADAL获取访问令牌对于v1.0 app。