Web API 2,OWIN 身份验证,SignOut 不注销
Posted
技术标签:
【中文标题】Web API 2,OWIN 身份验证,SignOut 不注销【英文标题】:Web API 2, OWIN Authentication, SignOut doesn't logout 【发布时间】:2014-08-24 12:04:53 【问题描述】:我正在做一些研究,以期使用 Bearer 令牌作为身份验证机制(即 AngularJS UI,在 Web API [2] 项目中通过 OWIN 进行身份验证)。
我的登录工作正常,角色信息和一切都很好,但我无法获取用于注销的令牌。
我的启动配置是这样的:
OAuthOptions = new OAuthAuthorizationServerOptions()
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = SESSION_TIMEOUT,
AllowInsecureHttp = true
;
而我的注销操作就是这样:
public HttpResponseMessage Logout()
var authentication = HttpContext.Current.GetOwinContext().Authentication;
authentication.SignOut(DefaultAuthenticationTypes.ExternalBearer);
return new HttpResponseMessage(HttpStatusCode.OK);
为简洁起见,我已将所有身份验证内容省略,但为了确认我在设置令牌时使用的是 ExternalBearer。
在我的 UI 中,我将令牌存储在本地存储中(此处不涉及 cookie,这是一个经过深思熟虑的设计决定)。所以我的 UI 上有一个 logout 按钮,Logout 操作被点击并且代码运行良好。
但是,如果我随后在 API 上执行需要授权的操作,请求仍会通过(即,即使用户应该已注销,用户仍会通过身份验证。
要么我遗漏了一些非常明显的东西(不会是第一次;-),要么这里发生了一些更基本的事情 - 最后我正在 ping @leastprivilege,因为我知道这是他们的领域。
我们将不胜感激地收到任何帮助或见解。
我唯一能想到的是令牌在服务器/API 端是无状态的,因此不能过期或注销。
如果是这样的话,我想我可以:
a) 添加一个刷新令牌,该令牌创建一个在过去过期的新令牌 - 这甚至可以工作吗? - 实际上取消它,它会发出一个新令牌......旧令牌仍然有效
b) 将不记名令牌存储在数据库中并每次检查,在注销时删除令牌(自然加盐、散列等)。然而,这只是让我们回到拥有一个有状态的服务器。
c) 当有人明确注销时,我可以(并且将会)从本地存储中删除该令牌,但是如果 一个坏人 可以拦截该令牌,则该令牌在技术上仍然有效。当然,以上所有内容都会超过 SSL,这应该会抑制 坏人/坏人。
d) 也许这就是为什么很多人将 Bearer 令牌存储在 cookie 中(作为一种存储机制)的原因,因此一旦您注销,至少 cookie 将在下次刷新时被删除。
抱歉,以上内容有点脑残,只是想抢先提问
【问题讨论】:
如果您通过以下建议解决了问题,请添加您的代码。对于您在哪里添加唯一 ID 并启用 IncludeJwtId,我真的有点困惑 【参考方案1】:只要我知道不记名令牌存在于客户端,所以我认为您不需要服务器端“注销”功能。只需从客户端本地存储中删除令牌即可将您注销。
【讨论】:
是的,我们将这样做(参见 C),但事实是 Bearer 令牌仍然有效。如果有人可以在删除之前拦截它,他们仍然可以冒充用户。 没问题。我很感谢你努力阅读它:-) 在不记名令牌上设置较短的过期时间(如30分钟)并在刷新令牌上实施数据库验证策略?【参考方案2】:由于 OAuth 不是身份验证协议,因此没有注销的概念。删除客户端上的访问令牌 - 这就是您所能做的。
如果您想在服务器端使令牌无效,请为其添加一个唯一 id 并在您的服务中跟踪 - 您需要手动构建类似的东西。
【讨论】:
我认为这证实了我的想法。谢谢。 令牌需要这样做。在 IdentityServer 例如每个客户端都有一个标志IncludeJwtId
。
那么认证的目的是什么。SignOut(DefaultAuthenticationTypes.ExternalBearer);
@leastprivilege 我正在使用 Oauth 连接到 Quickbooks Online。它有自己的身份验证服务器和身份验证客户端。连接并验证令牌后,我正在使用登录方法设置 owin athentication cookie。它设置了 User.Identity 并授权我的控制器,这些控制器不允许完美的匿名访问。但是当 QBO 会话到期时,它会在调用 api 时抛出 401。在这里,我发现了这个异常并要求退出。但是 mvc User.Identity 仍然有效。在这种情况下该怎么做,因为在我的情况下删除访问令牌不起作用。【参考方案3】:
这个问题已经存在了很长时间(并且也得到了回答),但我只是想表达一下自己的想法。
我会做与您的 (C) 选项类似的操作,但在不记名访问令牌上使用较短的到期时间,例如 10 或 20 分钟,这样当您注销并删除客户端上的令牌时,尽管从技术上讲令牌仍然有效,坏人将只有剩余的到期时间来玩你的有效令牌。
在实践中,我会将它与长寿命刷新令牌一起使用,以便在它过期并希望继续与 API 资源交互时获得新的不记名令牌,而无需再次进行身份验证。
【讨论】:
@Duncan 我想我不小心标记了答案。我已删除我的评论。很抱歉,感谢您的纠正。【参考方案4】:我在这里有一个很好的解决方案:http://www.nakov.com/blog/2014/12/22/webapi-owin-identity-custom-login-service/。它是基于 OWIN 和标准 ASP.NET Identity (Microsoft.AspNet.Identity.EntityFramework) 的 Web API OAuth 不记名令牌授权的自定义用户会话实现。它可以像大多数人所期望的那样工作:
Web API 会话在 30 分钟不活动后终止。 每次授权 HTTP 请求时,会话的生命周期都会延长 30 分钟。 注销工作正常:注销后持有者 access_token 变为无效(已被撤销)。GitHub 上提供了完整的工作源代码:https://github.com/SoftUni/SPA-with-AngularJS/tree/master/Ads-REST-Services
【讨论】:
非常好的博文。谢谢你的来信。以上是关于Web API 2,OWIN 身份验证,SignOut 不注销的主要内容,如果未能解决你的问题,请参考以下文章
具有混合身份验证 JWT 和 SAML 的 ASP.NET Web API 2.2 OWIN
身份验证/授权 MVC 5 和 Web API - Katana/Owin
Web API 2 OWIN Bearer Token cookie的用途?
OWIN 托管的 web api:使用 windows 身份验证并允许匿名访问
实施 Identity 2.1 + OWIN OAuth JWT 不记名令牌时如何从 Web API 控制器端点进行身份验证