如何使用OWIN直接使用令牌对OpenID Connect进行身份验证

时间:2015-09-28 14:53:19

标签: c# asp.net-mvc authentication azure owin

我有一个MVC Web应用程序,它使用OWIN / openid connect来验证https://login.windows.net/common/用户。它基于azure / office 365示例:https://github.com/OfficeDev/Research-Project-Code-Sample

如果我正确理解了身份验证流程,就会这样:

  1. 应用程序检查(基于cookie)是否已经有经过身份验证的用户
  2. 如果没有,则重定向到提供者授权页面(login.microsoftonline.com)
  3. 该网页使用验证码重定向回我的应用
  4. 我的应用程序再次使用访问令牌的身份验证代码调用提供程序(或者是id_token?)
  5. 我的应用程序(OWIN组件)提取各种openid属性并将它们设置在线程当前主体上
  6. 工作正常。

    现在我希望我的MVC应用程序调用我的Web API应用程序。 Web API应用程序永远不会被浏览器直接调用,但始终由MVC客户端调用。 Web API应用程序不使用cookie,并且如果使用不正确或过时的身份验证信息发出请求,则无法重定向。应该能够使用MVC应用程序获得的身份验证令牌调用We​​b API应用程序,并使用它在执行线程上设置ClaimsPrincipal。另一种选择可能是我在MVC应用程序中使用一些自定义解决方案来加密用户信息并将其发送到Web API,但这将是最后的手段。我更喜欢使用标准的owin。

1 个答案:

答案 0 :(得分:2)

如果您浏览Azure示例,您将找到所需内容。这里的关键是你想使用持票人代币。

在Azure中,您需要为WebApi端创建一个新应用程序,并与您的客户端应用程序建立关系。我使用相同的应用程序ID进行客户端身份验证和WebApi,但这不起作用。

在Web Api端,您需要使用Windows Azure Active Directory承载身份验证配置身份验证。

app.UseWindowsAzureActiveDirectoryBearerAuthentication(
    new WindowsAzureActiveDirectoryBearerAuthenticationOptions
    {
        TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters()
        {
            ValidAudience = ConfigurationManager.AppSettings["ida:AppApiResourceId"],
            SaveSigninToken = true
        },
        AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
        Tenant = ConfigurationManager.AppSettings["ida:Tenant"]
    });

您可以使用Identity中的引导上下文获取令牌。我正在尝试各种各样的方法来获得令牌,然后SO回答帮助我达到(Acquiring an Access token by using JWT used for AzureBearerAuthentication)。另请注意,resourceId是WebApi应用程序的appId。

if (identity == null || !identity.IsAuthenticated) return null;

AuthenticationResult authResult = null;

var context = identity.BootstrapContext as BootstrapContext;
var credential = new ClientCredential(AuthConfig.ClientId, AuthConfig.AppKey);
if (context != null && context.Token != null)
{
    authResult = authInfo.AuthContext.AcquireToken(resourceId, authInfo.Credential,
        new UserAssertion(context.Token));
}

return authResult;

当您向web api创建请求时,您需要在Authorization标头下的每个请求中发送承载令牌。

headers["Authorization"] = "bearer " + token;