1

我有一个使用 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,我看到了问题。

任何人都可以在这里帮助我如何解决这个问题。

4

0 回答 0