我有一个使用 ASP.NET (.NET Framework 4.8) 和 ASP.NET WEB API 2、SQL SERVER 2016 开发的 Web 应用程序。我正在使用带有 OpenIDConnect(授权代码流)的 Azure AD。
在此实现中,有一个容器 Web 应用程序 (ASP.NET),它托管 anguarjs (frontend) 、 web.config 以及相关的 bin 和 Global.asx 文件。除此之外,它也是包含所有 API 的 API 项目的占位符。API 项目有自己独立的 web.config 文件,并且这个 API 项目仅由前端 Web 应用程序使用。此 Web 应用使用 Azure AD (OIDC) 授权代码流进行身份验证,并具有自己的自定义授权。
这是整个身份验证流程:
testapp 托管为单个站点,API 项目托管为使用 IIS 10 的同一站点内的应用程序,如下所示:
API 项目使用与此实现中的 testapp 相同的应用程序池。
Azure AD 中有一个注册(整个 testpp 和 API)。Azure AD 中没有针对此实现的 API 项目单独注册。
现在导航到 URL:https ://testapp.com我被重定向到 Azure AD 登录页面,然后提供我的详细信息和登录,然后可以看到设置的 cookie 和 id_token 包括声明,但是当有一个调用到 API 在这种情况下,我看到未设置上下文对象,并且我看到没有维护任何声明。我在 API 项目级别有单独的身份验证和授权过滤器,只要 angularjs 前端应用程序对 webapis 进行任何调用,就会触发该过滤器。我还看到另一个问题,例如如果我直接在浏览器中导航到 URL:https//testapp.com/services/api/test/method,我没有触发 Azure AD 登录流程。
这是身份验证和授权过滤器:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Filters.Add(new TestAuthenticationAttribute());
config.Filters.Add(new TestAuthorizationAttribute());
}
}
TestAuthenticationAttribute.cs:
public class TestAuthenticationAttribute : ActionFilterAttribute, IAuthenticationFilter
{
private HttpAuthenticationContext _context;
public Task AuthenticateAsync(HttpAuthenticationContext context, System.Threading.CancellationToken cancellationToken)
{
_context = context;
return Task.FromResult(0);
}
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, System.Threading.CancellationToken cancellationToken)
{
return Task.FromResult(context.Result);
}
}
TestAuthorizationAttribute.cs:
public class TestAuthorizationAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
// retrieve principal and check authZ
IPrincipal principal;
if (!SecurityHelper.IsSecurityDisabled)
principal = actionContext.RequestContext.Principal as IClaimsPrincipal;
else
principal = actionContext.RequestContext.Principal as System.Security.Claims.ClaimsPrincipal;
if (principal != null && principal.Identity != null && principal.Identity.IsAuthenticated)
return true;
else
return false;
}
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
var response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "unauthorized");
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Federation", "permission required."));
actionContext.Response = response;
}
}
在上面的调试中,我看到 HttpActionContext actionContext 没有设置任何声明,因此没有设置主体对象,最后我看到未经授权的响应。
如果我尝试访问任何其他 URL,例如https://testapp.com/test/app.js,那么我可以看到 Azure AD 登录流程被触发。总的来说,我可以看到对 API 项目的调用因 HTTP 状态代码而失败:401(未授权)。
在 ADFS 实施的情况下,对 API 的调用看起来不错。我正在将身份验证模块从 ADFS 迁移到 Azure AD,我看到了问题。
任何人都可以在这里帮助我如何解决这个问题。