用于在应用程序中注销工作的OpenID重新验证

用于在应用程序中注销工作的OpenID重新验证,openid,access-token,openid-connect,oidc-client-js,Openid,Access Token,Openid Connect,Oidc Client Js,我有一个SPA应用程序,其中包含一些受OpenID身份验证保护的WebAPI方法。用户首先登录SPA应用程序,然后在应用程序中执行某些工作,然后需要通过与身份提供商重新验证来注销此工作 SPA应用程序使用oidc客户端js。为了强制重新验证,我们传入值为“login”的提示符参数。然后,用户将收到一个新的访问令牌,该令牌可用于调用WebAPI方法以注销工作 signoff WebAPI方法必须确保工作是以与首先登录到应用程序的相同的身份进行注销的。当应用程序仍然使用WsFed和会话cookies

我有一个SPA应用程序,其中包含一些受OpenID身份验证保护的WebAPI方法。用户首先登录SPA应用程序,然后在应用程序中执行某些工作,然后需要通过与身份提供商重新验证来注销此工作

SPA应用程序使用oidc客户端js。为了强制重新验证,我们传入值为“login”的提示符参数。然后,用户将收到一个新的访问令牌,该令牌可用于调用WebAPI方法以注销工作

signoff WebAPI方法必须确保工作是以与首先登录到应用程序的相同的身份进行注销的。当应用程序仍然使用WsFed和会话cookies(我们现在将其更改为OpenID)时,WebAPI能够断言传入标识与当前用户标识相同。但是,由于使用OpenID时我们不想使用会话cookie,因此WebAPI可能会要求登录访问令牌和注销访问令牌声明两者都是针对相同的身份。这似乎毫无意义。甚至可以做到吗?也许signoffwebapi只需要声明signoff标识具有在工作上注销的权限,而不考虑首先登录到应用程序的用户的身份

第二,用户必须单独签署单独的工作。因此,当用户在资源a上执行工作,通过与身份提供者重新验证来注销资源a上的工作,然后在资源B上执行工作时,WebAPI需要确保使用为资源B获得的访问令牌注销资源B上的工作,而不是使用先前为资源A获得的访问令牌

在重新验证以注销工作时,我们在重定向uri中指定资源Guid(这可能需要在ADFS中的回复url中指定通配符?它似乎不需要在IdentityServer3中进行特殊配置)。当我们使用WsFed时,SignoffWebAPI方法可以断言当前请求url与传入身份验证票证中包含的重定向uri相同。当使用OpenId时,我不认为访问令牌包含为其发出的重定向uri,对吗?那么,signoff WebAPI如何断言为当前正在注销的资源颁发的访问令牌呢

下面是一些基于我们如何使用WsFed的代码,但我不确定这是否适用于OpenID

app.UseIdentityServerBearerTokenAuthentication(
    new IdentityServerBearerTokenAuthenticationOptions
    {
        TokenProvider = new OAuthBearerAuthenticationProvider
        {
            OnValidateIdentity = context =>
            {
                var incomingIdentity = context.Ticket.Identity;

                // is the redirect uri even in the authentication ticket?
                incomingIdentity.AddClaim(new Claim(Business.ClaimTypes.RedirectUri,
                    context.Ticket.Properties.RedirectUri));

                // without session cookies, do we even have a current user at this stage?
                var user = context.OwinContext.Authentication.User;
                if (user.Identity.IsAuthenticated)
                {
                    incomingIdentity.AddClaim(new Claim(Business.ClaimTypes.RequestedBy,
                        user.Identity.Name));
                }

                return Task.CompletedTask;
            }
        }

    });


非常感谢您的帮助

您最终解决了问题吗?
public class SignoffAuthorizedAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var claimsPrincipal = (ClaimsPrincipal)filterContext.HttpContext.User;

        var redirectUriClaim = 
            claimsPrincipal.Claims.FirstOrDefault(c => c.Type == Business.ClaimTypes.RedirectUri);
        if (redirectUriClaim == null || filterContext.HttpContext.Request.Url != 
            new Uri(redirectUriClaim.Value, UriKind.RelativeOrAbsolute))
        {
            filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);
            return;
        }

        var requestedByClaim = 
            claimsPrincipal.Claims.FirstOrDefault(c => c.Type == Business.ClaimTypes.RequestedBy);
        if (requestedByClaim == null || claimsPrincipal.Identity.Name != 
            requestedByClaim .Value)
        {
            filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);                
        }
    }
}