Dun*_*ken 13 c# azure asp.net-web-api owin openid-connect
我尝试让OpenID Connect运行...我的Web API用户设法获得OpenID Connect Provider的授权码.我应该如何将此代码传递给我的ASP.NET Web API?如何配置OWIN中间件,以便我可以使用授权码获取访问令牌?
更新:SPA使用AJAX与我的Web服务(ASP.NET Web API)进行通信.在我的Web服务中使用OWIN Middleware.我将OpenIDConnect设置为身份验证机制.首次调用Web服务时,它成功将用户重定向到OpenID Connect Provider的登录页面.用户可以登录并获得授权码.AFAIK此代码现在可以(通过我的Web服务)用于访问令牌.但是,我不知道如何将此代码返回到我的Web服务(这是使用标头完成吗?)然后配置什么来获取访问令牌.我想我可以手动调用令牌端点,但我想利用OWIN组件.
and*_*fox 11
BenV已经回答了这个问题,但还有更多要考虑的问题.
class partial Startup
{
public void ConfigureAuth(IAppBuilder app)
{
// ...
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
Notifications = new OpenIdConnectAuthenticationNotifications() {
AuthorizationCodeReceived = (context) => {
string authorizationCode = context.Code;
// (tricky) the authorizationCode is available here to use, but...
return Task.FromResult(0);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
两个问题:
authorizationCode快速过期.存储它是没有意义的.AuthorizationCodeReceived只要authorizationCode未过期并存储在会话中,事件就不会被任何页面重新加载触发.你需要做的是调用AcquireTokenByAuthorizationCodeAsync哪个将缓存它并在内部正确处理TokenCache.DefaultShare:
AuthorizationCodeReceived = (context) => {
string authorizationCode = context.Code;
AuthenticationResult tokenResult = await context.AcquireTokenByAuthorizationCodeAsync(authorizationCode, new Uri(redirectUri), credential);
return Task.FromResult(0);
}
Run Code Online (Sandbox Code Playgroud)
现在,在每次调用资源之前,调用AcquireTokenSilentAsync以获取accessToken(它将使用TokenCache或静默使用refreshToken).如果令牌已过期,则会引发AdalSilentTokenAcquisitionException异常(调用访问代码续订过程).
// currentUser for ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")
AuthenticationResult authResult = await context.AcquireTokenSilentAsync(resourceUri, credential, currentUser);
Run Code Online (Sandbox Code Playgroud)
AcquireTokenSilentAsync如果缓存令牌,则调用非常快.
Ben*_*enV 10
看起来推荐的方法是使用AuthorizationCodeReceived事件来交换访问令牌的Auth代码. Vittorio有一个博客文章,概述了整体流程.
下面是一个例子GitHub上的这个示例应用程序中的Startup.Auth.cs代码来进行设置:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(clientId, appKey);
string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenantID), new EFADALTokenCache(signedInUserID));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceID);
return Task.FromResult(0);
},
...
}
Run Code Online (Sandbox Code Playgroud)
注意:AuthorizationCodeReceived只有在授权确实发生时才会调用该事件.如果已生成并存储了auth代码,则不会调用此事件.您必须注销或清除cookie才能强制执行此事件.
现在已内置到 Microsoft.Owin 4.1.0 或更高版本中。您可以使用SaveTokens使 id_token 可用,然后RedeemCode获取访问令牌并使其可用
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
ClientSecret = "redacted",
RedirectUri = postLogoutRedirectUri,
//This allows multitenant
//https://github.com/Azure-Samples/guidance-identity-management-for-multitenant-apps/blob/master/docs/03-authentication.md
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthenticationFailed = (context) =>
{
return Task.FromResult(0);
}
},
SaveTokens = true,
// Required for the authorization code flow to exchange for tokens automatically
// using this means you will need to provide RedirectUri and ClientSecret
RedeemCode = true
}
);
Run Code Online (Sandbox Code Playgroud)
然后您可以通过 HttpContext 对象访问令牌
var result = Request.GetOwinContext().Authentication.AuthenticateAsync("Cookies").GetAwaiter().GetResult();
string idToken = result.Properties.Dictionary["id_token"];
string accessToken = result.Properties.Dictionary["access_token"];
Run Code Online (Sandbox Code Playgroud)
来源: 如何使用 owin 和 Mvc 5 从 httpcontext 获取访问令牌
| 归档时间: |
|
| 查看次数: |
21666 次 |
| 最近记录: |