如何使用 OWIN 直接使用令牌通过 OpenID Connect 进行身份验证
How can I use OWIN to authenticate with OpenID Connect directly with a token
我有一个 MVC 网络应用程序,它使用 OWIN/openid 连接来通过 https://login.windows.net/common/. It's based on the azure / office 365 sample here: https://github.com/OfficeDev/Research-Project-Code-Sample 对用户进行身份验证。
如果我正确理解身份验证流程,它是这样的:
- 应用程序检查(基于 cookie)是否已经有经过身份验证的用户
- 如果没有,则重定向到提供商授权页面 (login.microsoftonline.com)
- 该页面使用授权码重定向回我的应用程序
- 我的应用再次使用访问令牌的授权代码调用提供商(或者它是 id_token?)
- 我的应用程序(OWIN 组件)提取各种 openid 属性并将它们设置在当前主体的线程上
效果不错。
现在我希望我的 MVC 应用程序调用我的 Web API 应用程序。 Web API 应用程序从不直接由浏览器调用,而总是由 MVC 客户端调用。 Web API 应用程序不使用 cookie,如果使用不正确或过时的身份验证信息发出请求,则无法重定向。 Web API 应用程序应该能够使用 MVC 应用程序获得的身份验证令牌进行调用,并使用它在执行线程上设置 ClaimsPrincipal。我的另一种选择可能是在 MVC 应用程序中使用一些自定义解决方案来加密用户信息并将其发送到 Web API,但这是最后的选择。我更愿意使用标准 owin。
如果您深入研究 Azure 示例,就会找到所需的内容。这里的关键是你想使用不记名令牌。
在 Azure 中,您需要为 WebApi 创建一个新的应用程序,并与您的客户端应用程序建立关系。我在我的客户端身份验证和 WebApi 中使用相同的应用程序 ID,但这不起作用。
在 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 的 bootstrap 上下文获取令牌。在 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;
当您创建对网络的请求时 api 您需要在授权 header 下在每个请求中发送不记名令牌。
headers["Authorization"] = "bearer " + token;
我有一个 MVC 网络应用程序,它使用 OWIN/openid 连接来通过 https://login.windows.net/common/. It's based on the azure / office 365 sample here: https://github.com/OfficeDev/Research-Project-Code-Sample 对用户进行身份验证。
如果我正确理解身份验证流程,它是这样的:
- 应用程序检查(基于 cookie)是否已经有经过身份验证的用户
- 如果没有,则重定向到提供商授权页面 (login.microsoftonline.com)
- 该页面使用授权码重定向回我的应用程序
- 我的应用再次使用访问令牌的授权代码调用提供商(或者它是 id_token?)
- 我的应用程序(OWIN 组件)提取各种 openid 属性并将它们设置在当前主体的线程上
效果不错。
现在我希望我的 MVC 应用程序调用我的 Web API 应用程序。 Web API 应用程序从不直接由浏览器调用,而总是由 MVC 客户端调用。 Web API 应用程序不使用 cookie,如果使用不正确或过时的身份验证信息发出请求,则无法重定向。 Web API 应用程序应该能够使用 MVC 应用程序获得的身份验证令牌进行调用,并使用它在执行线程上设置 ClaimsPrincipal。我的另一种选择可能是在 MVC 应用程序中使用一些自定义解决方案来加密用户信息并将其发送到 Web API,但这是最后的选择。我更愿意使用标准 owin。
如果您深入研究 Azure 示例,就会找到所需的内容。这里的关键是你想使用不记名令牌。
在 Azure 中,您需要为 WebApi 创建一个新的应用程序,并与您的客户端应用程序建立关系。我在我的客户端身份验证和 WebApi 中使用相同的应用程序 ID,但这不起作用。
在 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 的 bootstrap 上下文获取令牌。在 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;
当您创建对网络的请求时 api 您需要在授权 header 下在每个请求中发送不记名令牌。
headers["Authorization"] = "bearer " + token;