使用OAuth2对Azure AD进行身份验证以调用WebAPI

时间:2017-03-01 21:07:18

标签: c# azure asp.net-web-api oauth-2.0 azure-active-directory

我正在尝试创建一个将在AWS中托管的新Web应用程序。此应用程序需要通过OAuth2从Azure Active Directory验证用户身份。这是我到目前为止所做的工作以及我曾经让我到那里的步骤:

1)用户从“login.microsoftonline.com”登录后,我可以生成“代码”。为此,我在Azure AD中设置了一个新应用程序,我的Web应用程序指示用户登录。我还在Azure AD中设置了API应用程序,我将其用作查询字符串中的“resource”参数当我将用户引导到login.microsoftonline.com端点

2)使用上面#1生成的“代码”,我可以通过调用应用程序的/ token端点生成我的授权令牌。我能够通过传递相同的资源值(我最终想要使用的API的URL),代码,我的客户端ID和我的客户端密钥来实现这一点

3)来自#2的令牌响应发送下来的token_type,expires_in,scope,access_token,refresh_token和id_token属性,所有这些属性都有值。我能够将id_token解码为JWT,并在声明对象中显示登录用户的正确用户信息

4) HERE'S STIE 然后我尝试调用我的API应用程序,该应用程序也使用我在#3中获得的access_token在Azure AD中注册,并在“授权”标题,该值为“Bearer xyz123 ......”如果我没有对API应用程序进行任何授权,我会得到我期望的结果,但是,如果我设置了[Authorize]属性在类甚至Get()方法上,我总是得到401(未经授权)。我确定我需要连接其他东西我只是不确定是什么。我找到了这个资源:https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad但它谈到了用api管理注册我的API,我认为我不需要这样做(如果我不需要,我肯定不想这样做。)

我正在创建的api将依赖于能够获取登录用户的身份,我假设我可以从持有人令牌中提取,我只是不知道如何......

任何帮助和指导将不胜感激。

编辑以包含工作解决方案: 以下是我在启动课程中根据以下接受的答案使用的内容。请注意,“audience”值是我正在调用的我需要访问的API端点的URL。租户是我们在组织中绑定的自定义URL,如果您不提供有效的租户价值,您可能会收到一条例外情况,说“响应状态代码并不表示成功:404(未找到)”。您需要可以从Nuget获取的Azure Active Directory程序集:Install-Package Microsoft.Owin.Security.ActiveDirectory

public partial class Startup
{
    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {

        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Audience = "https://myapi.azurewebsites.net/",
                Tenant = "my.custom.url.com",
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidateIssuer = false
                }
            });
    }
}

这里是我用来从需要访问权限的应用程序发出请求的post参数。

        body.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
        body.Add(new KeyValuePair<string, string>("code", code)); // code from response
        body.Add(new KeyValuePair<string, string>("redirect_uri", "http://localhost:51015/redirect"));
        body.Add(new KeyValuePair<string, string>("client_id", "xxxxxxx-8829-4294-b2c9-xxxxxxxxxx")); // client id of this application making the request
        body.Add(new KeyValuePair<string, string>("client_secret", "PxxxxxxxxxxxxSnTJ4Uh63Voj+tkxxxxxxx="));
        body.Add(new KeyValuePair<string, string>("resource", "https://myapi.azurewebsites.net/")); // same value goes here that is in the audience value of the api, this is also the same value that is passed in the resource parameter of the query string on the redirect to the login to obtain the "code" in the previous step

2 个答案:

答案 0 :(得分:2)

这取决于您如何保护Web API。通常,我们可以使用以下代码使用Azure AD保护Web API:

public partial class Startup
{
    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {

        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Audience = ConfigurationManager.AppSettings["ida:Audience"],
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                 TokenValidationParameters= new System.IdentityModel.Tokens.TokenValidationParameters {
                     ValidateIssuer=false
                 }
            });
    }
}

受众是您在Azure门户网站上注册的应用的 ClientId 。在这种情况下,我们将此应用程序用作客户端和资源。然后我们可以像下面的请求那样请求访问令牌:

POST: https://login.microsoftonline.com/{tenantId}/oauth2/token
resource={clientId}&client_id={clientId}&code={authorizationCode}&grant_type=authorization_code&redirect_uri={redirectUri}&client_secret={clientSecret}

此令牌适用于通过上述代码保护的Web API的授权。有关保护Web API的更多详细信息,请参阅here

答案 1 :(得分:0)

在Fiddler中检查“与身份验证失败相关的任何其他详细信息,可能会有”无效的受众“等详细信息。您需要知道失败的根本原因(401错误)才能解决此问题。

相关问题