关于prompt=consent、OpenID Connect says:
授权服务器应该在向客户端返回信息之前提示最终用户同意。如果它不能获得同意,它必须返回一个错误,通常是consent_required。
在 Microsoft 身份平台中,这意味着最终用户将要求提供同意,即使用户之前已授予同意,或者(对于工作或学校帐户,由管理员代表用户)。
如果用户无权同意所请求的权限(例如,因为用户同意被禁用或限制),使用prompt=consent 将始终导致用户被硬阻止。
在大多数情况下,使用prompt=consent不是最好的方法。通常考虑三种场景prompt=consent:
-
您已更改所需权限。所需权限已更改(例如,已添加或删除权限),用户需要同意新的权限集。
-
您想通知用户。应用开发者希望确保通知用户该应用将被授权行使哪些权限(即使管理员已经代表相关用户同意)。
-
您需要用户本人的同意,而不是管理员的同意。应用开发者希望确保最终用户自己提供同意,而与管理员之前可能授权的内容无关。
如果您更改了所需的权限
动态定义请求的权限时
在the v2.0 endpoint 上,scope 参数可用于dynamically 请求委托权限列表。例如,请求https://api.example.com标识的API的read和export委托权限:
scope=openid https://api.example.com/read
Azure AD 将确保已授予所有请求的权限,并尝试提示您同意任何尚未授予的权限(并且仅针对这些权限)。如果请求的权限都已被授予,则颁发的令牌将包括所有授予的权限(即使它们没有被特别请求)。
一般来说,在使用 v2.0 端点的增量同意能力时,应该不使用prompt=consent。如果需要,Azure AD 将负责提示增量同意。
当请求的权限是静态定义时
应用还可以仅识别它正在为其请求访问令牌的资源(即 API),具体权限是为应用静态定义的。使用 v2.0 端点,这是在 scope 参数中完成的,使用 the special .default permission value:
scope=openid https://api.example.com/.default
在the v1.0 endpoint 中,这是使用resource 参数实现的:
resource=https://api.example.com
所需权限列表在应用注册的静态列表中配置。在 Azure 门户中,此列表位于 Azure AD > 应用注册 > API 权限中的已配置权限。在 Microsoft Graph 中的 Application 实体(以及 app manifest)中,它存储在 requiredResourceAccess 属性中。
在收到此类请求时(在 v1 或 v2 端点上),Azure AD 将检查已为请求的资源授予了哪些权限:
- 如果 no 已为请求的资源授予委派权限OR 如果使用了
prompt=consent,Azure AD 将尝试从静态提示提供所有必需的权限-定义的列表。这将包括其他 API 的权限(如果已配置)。
- 如果已为请求的资源授予任何委派权限,Azure AD 将颁发具有所有授予权限的令牌。响应的
scopes 参数 将包括访问令牌中包含的权限列表。
依赖于静态定义的所需权限(即 v2 上的 /.default 或 v1 上的 resource)的应用程序不应对每个登录请求使用 prompt=consent。相反,应用程序应该:
-
在没有
prompt=consent的情况下进行登录。
- 检查响应的
scope参数:
- 如果列出了所需的权限,则无需进一步操作。
- 如果不是(例如,如果在用户最初同意该应用后将新权限添加到所需权限列表中),只有在此用户才应该再次被送回,这次是 @ 987654353@.
此策略确保用户可以在管理员代表他们同意时登录应用(例如,因为他们无权自行同意),并且仅强制同意提示(或升级给管理员代表他们同意)在配置新权限时。
如果你想通知用户
使用prompt=consent 不是一个好方法,如果目标只是通知用户应用程序已被授权行使哪些权限(由用户之前,或由管理员在代表用户)。
相反,应用程序可以使用令牌响应的scope 参数来构建所需的中断体验(例如,在用户被重定向回应用程序并检索令牌之后,但在继续之前),通知被授予了哪些权限的用户。
如果您需要用户而不是管理员的同意
当应用程序要求用户同意所请求的权限并且希望不接受管理员代表用户授予的同意时,可能存在非常特殊的情况。
在这种情况下,可以在所有登录中使用prompt=consent,但需要考虑一些重要的注意事项:
- 在许多组织中,user consent is disabled 或受限。如果用户无权同意为您的应用配置的权限,他们将无法使用您的应用。
- 每次登录都会提示用户同意,即使用户自己之前已经同意。
- 由于这是一个查询参数,知识渊博的用户可以很容易地在请求发出之前拦截该请求,并删除
prompt=consent(如果之前已经同意,则不会提示他们同意)。
在这种情况下,应用在用户登录后实现单独的同意授予体验可能会更好(类似于前面描述的“通知”场景),将应用的附加Microsoft 标识平台提供的同意体验中的同意要求。