Azure Active Directory注销或清除本机应用程序的令牌缓存 [英] Azure active directory Logout or clear token cache for native app

查看:91
本文介绍了Azure Active Directory注销或清除本机应用程序的令牌缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C#Web API REST服务后端,我为CMS,网页和Angular2应用程序提供服务(这与此处有关)。 Angular应用程序需要通过后端发送用户名和密码(原始凭据)进行身份验证,后端使用它们来请求对Azure Active Directory的access_token(具有 UserCredentials ),以及将access_token发送回Angular应用,以用于其请求中的授权( Authorization:Bearer )。这就是我进行身份验证的方式:

I have a C# web API REST services back-end, I provide services for a CMS, a web page, and Angular2 app (this is the relevant here). The Angular app needs authenticate through the back-end sending username and password (raw credentials), the backend uses these to request an access_token to Azure Active Directory (with UserCredentials), and sends the access_token back to the Angular app, to be used for authorization in it's requests (Authorization: Bearer). This is the way I'm authenticating:

UserCredential uc = new UserPasswordCredential(user, password);
AuthenticationContext authContext = new AuthenticationContext(Constants.authority, false);
AuthenticationResult result = authContext.AcquireTokenAsync(Constants.audience, Constants.clientIdNative, uc).Result;

问题是它会为该令牌生成一个小时的缓存,并且如果用户注销并仅使用用户或用户+错误的密码再次输入,身份验证仅查找该用户的缓存,并忽略或不验证密码。在一个小时的窗口中,任何人都可以使用用户名登录。

The thing is that it generates a one hour cache for that token, and if the user logs out and enters again just with the user or user + wrong password the Authentication just look up the cache for that user and ignores or doesn't validate the password. In the one hour window anyone can get in just with the username.

我在这里和其他许多网站上找到了注销或清除令牌的方法,但这些方法并非如此适用于我的后端,因为它是无状态的。我不管理它们之间的会话或HTTP上下文。如果有人可以指导解决此问题,则我使用的是 Microsoft.IdentityModel.Clients.ActiveDirectory 的最后一个程序集,版本3.13.1.846,我知道方法 AcquireTokenByAuthorizationCodeAsync 不会查找缓存,但是没有可用于原始凭据的实现。

I found here and on many other sites ways of logging out or clearing the token, but those are not applicable for my backend because it's stateless. I don't manage sessions or HTTP contexts between these. If anyone can guide to solve this, I'm using the last assembly of Microsoft.IdentityModel.Clients.ActiveDirectory, version 3.13.1.846, I know the method AcquireTokenByAuthorizationCodeAsync doesn't look up for cache but there's no implementation for use with raw credentials.

谢谢大家,希望对我有所帮助。

Thanks guys and hope you can help me.

推荐答案

强烈建议您遵循的策略反对。通常,对于您的应用程序来说,完全不收集用户名和密码是一种不好的做法。此流程(资源所有者密码凭证(ROPC)授权流程)仅用于对于其他机制不可用的情况。从OAuth 2.0规范开始(强调):

The strategy you are following is highly recommended against. It is generally bad practice for your application to collect a username and password at all. This flow (the Resource Owner Password Credentials (ROPC) Grant flow) is only intended for scenarios where other mechanisms are unavailable. From the OAuth 2.0 spec (emphasis added):


1.3.3。资源所有者密码凭证

1.3.3. Resource Owner Password Credentials

资源所有者密码凭证(即用户名和密码)
可以直接用作授权授予来获取访问权限
令牌。仅当资源所有者和客户端之间具有
的高度信任(例如,
客户端是设备操作系统的一部分或特权较高的
应用程序的一部分)时,才应使用凭据。 ),,以及在没有其他
美元可用授权(例如授权代码)的情况下

The resource owner password credentials (i.e., username and password) can be used directly as an authorization grant to obtain an access token. The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application), and when other authorization grant types are not available (such as an authorization code).

即使此授予类型要求客户直接访问
资源所有者凭证,资源所有者凭证用于单个请求
并交换访问令牌。通过将
凭据与长期访问令牌或刷新令牌进行交换,这种
授予类型可以消除客户端存储
资源所有者凭据以供将来使用的需要。

Even though this grant type requires direct client access to the resource owner credentials, the resource owner credentials are used for a single request and are exchanged for an access token. This grant type can eliminate the need for the client to store the resource owner credentials for future use, by exchanging the credentials with a long-lived access token or refresh token.

在针对Azure AD使用此流时,您会发现此流通常会失败,因为有时用户需要提供的不仅仅是一个用户名和密码。

When using this flow against Azure AD, you'll find that this flow will often fail, as users are sometimes required to provide more than just a username and password. Some examples of where this won't work:


  • 用户需要同意应用程序所请求的权限

  • 用户的密码已过期,需要更改

  • 用户的凭据涉嫌受到入侵

  • 用户登录否则被视为可疑(在您的情况中更有可能,因为登录似乎来自Web服务器,而该Web服务器可能不在用户所在的位置)

  • 用户已启用多因素身份验证

  • 用户是联合域名的一部分(其中权威身份提供者不是Azure AD)

  • The user needs to consent to the permissions the application is requesting
  • The user's password expired and needs to be changed
  • The user's credentials are suspected of being compromised
  • The user's sign-in is otherwise considered suspicious (more likely in your scenario, since the sign-ins will appear to be coming from web server, which is likely not located where the user is)
  • The user has multi-factor authentication enabled
  • The user is part of a federated domain name (where the authoritative identity provider is not Azure AD)

基本上,通过使用这种方法,您可以绕过OAuth 2.0和Azure AD提供的大多数安全性改进,并且可以将自己,应用程序和用户置于

Basically, by using this approach, you are bypassing most of the security improvements provided by OAuth 2.0 and Azure AD, and you are putting yourself, your application and your users at risk by using the username/password flow in a way that it was not intended to be used.

此外,而Azure AD 服务确实会带来风险当前支持ROPC流程,您会发现在某些情况下实际上已从库中删除了对该流程的支持(例如问题#320从iOS / Android / WinRT和问题#462 PCL UserCredential不再支持密码)。

Also, while the Azure AD service does currently support the ROPC flow, you'll find that support for this flow is actually being removed from libraries in some cases (e.g. Issue #320 Remove non-interactive auth from iOS/Android/WinRT and Issue #462 PCL UserCredential no longer supports password).

回答您的特定问题

(悬停以查看您不应该做的事情,但可以回答有关令牌缓存的问题。)

(Hover to see what you should NOT do in your case, but answers your question about token caching.)


跳过令牌缓存的一种方法是简单地使用构造函数签名,该签名采用 TokenCache 值并传递空的 TokenCache 值:


One way to skip token caching is to simply use the constructor signature that takes a TokenCache value and pass in a null TokenCache value:

AuthenticationContext authContext =
    new AuthenticationContext(Constants.authority, false, null);

一种更好(但仍然很糟糕)的方法

(真的,不要这样做,您不妨跳到下一节...)

(Really, don't do this, you may as well skip to the next section...)


如果您发现自己的本机客户端应用程序绝对必须使用用户名/密码流,并且您接受了风险并愿意忍受这些风险以及所有其他缺点,那么您Angular应用应该直接向Azure AD 发出令牌请求 >不通过您的API后端。然后,可以使用接收到的访问令牌对您的API(或受Azure AD保护的其他API,根据您在令牌中指定为资源的内容)发出经过身份验证的请求

If you find yourself in a situation where your native client app absolutely MUST use the username/password flow, and you accept the risks and are willing to live with them and all the other shortcomings, your Angular app should be making the token request to Azure AD directly, not passing through your API back-end. The received access token can then be used to make authenticated requests against your API (or other APIs which are secured by Azure AD, depending on what you specify as the resource in the token request).

正确的方法

正确的方法是让您的本机客户端应用程序利用任何受支持的流程,这些流程涉及将用户(通过Web浏览器或Web视图)发送到Azure AD进行身份验证。这样可以确保正确处理以上所有情况下的用户体验(同意提示,更改密码提示,多因素身份验证提示等)。它还将允许您利用令牌缓存(改善整体体验,因为您没有为每次后端调用添加令牌请求)。

The correct approach is for your native client application to make use of any of the supported flows that involves sending the user (via the web browser or a web view) to Azure AD to authenticate. This ensures that the user experience in all the scenarios above is correctly handled (consent prompt, change password prompt, multi-factor auth prompt, etc.). It will also allow you to make use of a token cache (improving the overall experience, since you're not adding a token request for every call to the backend).

用户通过身份验证后,您的应用将具有访问令牌,刷新令牌和ID令牌。您可以直接在应用程序后端使用这些令牌。如果您的应用程序后端需要在用户上下文中调用其他API,则可以通过将从本机客户端应用程序获取的访问令牌交换为另一用户的访问令牌,从而将访问令牌交换给另一个资源。访问令牌最初是被授予的(实际上,有一个示例可以做到这一点: active-directory-dotnet-webapi-onbehalfof )。

Once the user has authenticated, your app will have a access token, a refresh token, and an ID token. You can use these tokens directly against your application backend. If your app's backend needs to make calls to other APIs in the context of the user, it can do so by exchanging the access token it got from the native client app for an access token to another resource, on behalf of the user to whom the access token was originally granted (in fact, there's a sample that does exactly this: active-directory-dotnet-webapi-onbehalfof).

对于Angular2应用,我建议您看一下 ADAL for JavaScript 库,以及一些似乎增加了对Angular2支持的包装器库(例如 angular2-adal )。

For an Angular2 app, I recommend taking a look at the ADAL for JavaScript library, in combination with some of the wrapper libraries that have appeared to add support for Angular2 (e.g. angular2-adal).

这篇关于Azure Active Directory注销或清除本机应用程序的令牌缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆