Azure AD B2C刷新令牌/ID令牌iOS Swift 4



我正在开发一个iOS应用程序,利用带有AADB2C的ROPC流作为支持它的后端端点。https://login.microsoftonline.com/{TENANTNAME}.onmicrosoft.com/oauth2/v2.0/token?p={ROPC Policy Name}

在客户首次使用电子邮件/密码成功登录时,我已成功请求并检索到access tokenrefresh tokenID token

在成功登录后,每次登录后,我们都希望利用生物识别技术(触摸/人脸ID(。我的第一个想法是将refreshToken存储在Keychain中,在强制用户输入他/她的电子邮件/pw之前检查是否存在refreshToken

如果存在refreshToken,那么我想我会使用对令牌端点的调用,使用?p=refresh_token而不是?p={INSERT ROPC Policy Name},如果我返回成功,那么我会使用Touch/Face ID登录。

我的另一个想法是只使用令牌ID进行身份验证。

因此,我的问题有两个:

  1. iOS本机应用程序使用刷新令牌或ID令牌的更好做法是什么。

  2. 我尝试过使用刷新令牌,用?p=refresh_token替换{ROPC Policy Name}参数,但每次尝试配置请求时,都会收到一个错误,说"The request body must contain the following parameter: 'grant_type'"我添加了"refresh_token"作为密钥grant_type的值,但仍然会出现错误。——为什么会这样?如果刷新令牌grant_type更好,我该如何绕过它。

你是对的。

您可以将刷新令牌保存到密钥链中,并使用Face或Touch ID保护此刷新令牌的使用。

"在Azure AD B2C中配置资源所有者密码凭据流"文档的"兑换刷新令牌"部分描述了如何兑换为资源所有者策略颁发的刷新令牌:

POST /{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&response_type=id_token
&client_id={client_id}
&resource={client_id}
&refresh_token={refresh_token}

谢谢@Chris Padgett。我使用一个稍微修改过的请求,就可以使用AppAuth启动并运行它。这是我的密码。

let authorizationEndpoint = URL(string: "https://login.microsoftonline.com/{TENANT_NAME}.onmicrosoft.com/oauth2/v2.0/authorize?p={ROPC_POLICY_NAME}")
let tokenEndpoint = URL(string: "https://login.microsoftonline.com/{TENANT_NAME}.onmicrosoft.com/oauth2/v2.0/token?p={ROPC_POLICY_NAME}")
let configuration = OIDServiceConfiguration(authorizationEndpoint: authorizationEndpoint!, tokenEndpoint: tokenEndpoint!)
//Configuring the token request
let tokenExchangeRequest = OIDTokenRequest(
configuration: configuration,
grantType: OIDGrantTypeRefreshToken,
authorizationCode: nil,
redirectURL: self.redirectUri!,
clientID: self.clientId,
clientSecret: nil,
scope: "openid (self.clientId) offline_access",
refreshToken: {INSERT_REFRESH_TOKEN_HERE},
codeVerifier: nil,
additionalParameters: nil
)
//Performing token request
OIDAuthorizationService.perform(tokenExchangeRequest, callback: { tokenResponse, error in
if tokenResponse == nil {
print("Token request error: %@", error?.localizedDescription as Any)
} else {
guard let tokenResponse = tokenResponse else { return }
...handle tokenResponse how you need to...
}
})

最新更新