我目前正在尝试使用ADFS 2016验证角度7应用程序(使用angular-oauth2-oidc)。到目前为止,它运作良好。当我访问应用程序时,我被重定向到ADFS登录页面,在那里我输入我的凭据并获得令牌。
现在,当应用程序调用Web API时,它会在请求标头中发送访问令牌。 ADFS返回的访问令牌如下所示:
{
"aud": "microsoft:identityserver:xxx",
"iss": "http://xxx/adfs/services/trust",
"iat": 1554561406,
"nbf": 1554561406,
"exp": 1554565006,
"apptype": "Public",
"appid": "xxx",
"authmethod": "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
"auth_time": "2019-04-06T12:21:39.222Z",
"ver": "1.0",
"scp": "profile openid"
}
问题是Web API必须知道进行调用的用户的ID(因为在应用程序级别定义了一些权限)。我看到here,我可以添加对访问令牌的声明,我做了。但是,在阅读Internet上的文章时,我读到显然访问令牌不应该用于识别用户,因此我不知道添加Web API用于识别用户的声明是否正确。
但是,我读了here
访问令牌拥有的唯一用户信息是位于子声明中的用户ID。
但默认情况下,ADFS不提供“子”令牌。如果我自己添加一个包含用户电子邮件地址的“子”声明,或者我必须以不同的方式继续进行,这是否正确?
是的,访问令牌不应该用于识别用户。但是,如果您可以在访问令牌中获取用户标识符,并且您需要了解用户,那么这可能是最简单的方法。但它是针对您的auth服务器的特定于实现的。
标准方法是询问profile
范围(您所做的)并从userinfo
端点获取信息(请参阅OpenID Connect RFC)。如果使用这种方式,您可能希望缓存响应,因此您不需要在每个客户端请求上进行此HTTP调用。
如果您的后端API仅由Angular应用程序使用且不应由第三方调用,您还可以考虑将后端用作OAuth2客户端,该客户端接收授权代码并将其交换为ID令牌。然后,它可以在会话中保存用户的身份(从ID令牌中读取)并发出标识会话的cookie。因此,前端不需要在每个请求上发送令牌。这会使后端有状态,但可能更容易实现。