【问题标题】:401 Unauthorized errors when accessing WebApI from AngularJS/ADAL.js client从 AngularJS/ADAL.js 客户端访问 WebApI 时出现 401 未经授权的错误
【发布时间】:2017-07-31 07:47:34
【问题描述】:

我有一个带有 Angular 前端的自托管 Web api 应用程序,我现在需要开始通过 Azure Active Directory 对用户进行身份验证。

我已经下载了 SinglePageApp 示例,并且我已经对其进行了设置并使其成功运行。 https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp-dotnet-webapi

当对我自己的应用程序应用必要的更改时,我可以成功地将用户重定向到 Azure 登录屏幕并使用 adal.js/adal_angular.js 取回 userProfile。每当我调用我的 API 时,我都会收到 401 未经授权的错误,但是使用 Fiddler,我可以看到承载令牌已添加到每次调用的 HTTP 标头中。

这是我的 AdalAngular 设置:

.config(["$httpProvider", "adalAuthenticationServiceProvider", ($httpProvider, adalProvider) => {
            adalProvider.init(
            {
                instance: "https://login.microsoftonline.com/",
                tenant: "<snip>.onmicrosoft.com",
                clientId: "<snip>",
                extraQueryParameter: "nux=1",
                cacheLocation: "localStorage" // enable this for IE, as sessionStorage does not work for localhost.
            },
            $httpProvider);

这是我的 startup.cs 代码:

public void Configuration(IAppBuilder appBuilder)
    {

        ConfigureWebApi(appBuilder);
        ConfigureAuth(appBuilder);
        ConfigureFileSystem(appBuilder);
        appBuilder.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    }

private void ConfigureWebApi(IAppBuilder appBuilder)
    {
        // Configure Web API for self-host. 
        HttpConfiguration config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        appBuilder.UseWebApi(config);
    }

    private void ConfigureAuth(IAppBuilder app)
    {
        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Tenant = ConfigurationManager.AppSettings["ActiveDirectoryTenant"],
                Audience = ConfigurationManager.AppSettings["ActiveDirectoryApplicationId"]
            });
    }

    private void ConfigureFileSystem(IAppBuilder appBuilder)
    {

        //Set the Welcome page to test if Owin is hosted properly
        appBuilder.UseWelcomePage("/welcome.html");
        appBuilder.UseErrorPage(new Microsoft.Owin.Diagnostics.ErrorPageOptions() { ShowExceptionDetails = true });
        var physicalFileSystem = new PhysicalFileSystem(@".\wwwroot");
        if (ConfigurationManager.AppSettings.AllKeys.Contains("ContentPath"))
        {
            var path = ConfigurationManager.AppSettings["ContentPath"];
            physicalFileSystem = new PhysicalFileSystem(path);
        }
        FileServerOptions fileOptions = new FileServerOptions();

        fileOptions.EnableDefaultFiles = true;
        fileOptions.RequestPath = PathString.Empty;
        fileOptions.FileSystem = physicalFileSystem;
        fileOptions.DefaultFilesOptions.DefaultFileNames = new[] { "index.html" };
        fileOptions.StaticFileOptions.FileSystem = fileOptions.FileSystem = physicalFileSystem;
        fileOptions.StaticFileOptions.ServeUnknownFileTypes = true;
        appBuilder.UseFileServer(fileOptions);
    }

ActiveDirectoryTenant 和 ActiveDirectoryApplicationId 在我的 app.config 中的位置,并且与我的 angular adalProvider.init 代码中的配置完全匹配。

最后,我的 ApiController 看起来像这样:

 [Authorize]
[RoutePrefix("api/connection")]
public class ServerConnectionController : ApiController
{
    [Route("all")]
    [HttpGet]
    public HttpResponseMessage GetAllConnections()
    {
        HttpResponseMessage response;
        try
        {
            string owner = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            var connections = _iDataAccess.GetAllConnections().ToList();
            response = Request.CreateResponse(HttpStatusCode.OK, connections);
        }
        catch (Exception ex)
        {
            response = GetExceptionResponseMessage(ex);
        }

        return response;
    }
}

如前所述,Fiddler 捕获的 HTTP 请求标头看起来不错,并且我的 ADAL.js userInfo.profile 上的 aud 属性是正确的 appid。

对可能缺少的内容有什么建议吗? 请注意,这不是基于原生 Web 的应用程序,它是自托管的,这意味着 Web 服务作为 Windows 服务在 localhost 上运行,而不是在 IIS 中。

我已将站点配置为使用 HTTPS,但无论 HTTP 或 HTTPS 流量如何,我都会遇到同样的问题。

感谢收听!

【问题讨论】:

  • 我自己的实现和你实现的唯一区别是我声明了 ConfigureAuth(appBuilder);作为 Startup.cs 配置方法中的第一行
  • 这似乎是问题所在,非常感谢您的建议!
  • 好的,太好了!我应该将此添加为答案,以便关闭此问题吗?
  • 请。如果你能解释为什么这里的顺序很重要,那就更好了。

标签: angularjs asp.net-web-api2 adal.js


【解决方案1】:

您需要将ConfigureAuth(appBuilder); 声明为 Startup.cs 配置方法中的第一行。你可以找到一个很好的解释 here 为什么它需要被声明为第一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-09
    • 2018-07-07
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 2011-09-15
    相关资源
    最近更新 更多