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

时间:2018-08-04 05:51:23

标签: ios swift azure azure-ad-b2c

我正在开发一个iOS应用,将ROPC流程与AADB2C一起用作支持此功能的后端端点。 https://login.microsoftonline.com/{TENANTNAME}.onmicrosoft.com/oauth2/v2.0/token?p={ROPC Policy Name}

在客户首次成功使用电子邮件/密码登录后,我已经能够成功请求和检索access tokenrefresh tokenID token

成功登录后,以后每次登录后,我们都希望利用生物识别技术(触摸/面部识别码)。我的第一个想法是将refreshToken存储在钥匙串中,在强制用户输入其电子邮件/密码之前检查refreshToken是否存在。

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

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

因此,我的问题有两个方面:

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

  2. 我尝试使用刷新令牌,将{ROPC Policy Name}参数替换为?p=refresh_token,但是每次尝试配置请求时,都会收到一条错误消息,提示"The request body must contain the following parameter: 'grant_type'" 我添加了“ refresh_token”作为键grant_type的值,并且该错误仍然出现。 -为什么会这样?如果刷新令牌grant_type更好,该如何解决。

2 个答案:

答案 0 :(得分:2)

你是对的。

您可以将刷新令牌保存到钥匙串中,并通过Face或Touch ID保护该刷新令牌的使用。

The "Redeem a refresh token" section中的

the "Configure the resource owner password credentials flow in Azure AD B2C" document描述了如何兑换为资源所有者策略发出的刷新令牌:

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}

答案 1 :(得分:0)

感谢@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...
    }
})