简体   繁体   English

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

[英]Azure AD B2C Refresh Token/ID Token iOS Swift 4

I'm developing an iOS app, utilizing the ROPC flow with AADB2C as the backend endpoints supporting this. 我正在开发一个iOS应用程序,利用ROPC流程和AADB2C作为后端端点支持这一点。 https://login.microsoftonline.com/{TENANTNAME}.onmicrosoft.com/oauth2/v2.0/token?p={ROPC Policy Name}

I've successfully been able to request and retrieve an access token , refresh token and ID token upon a customer's first time successfully logging in using an email/password. 我成功地能够在客户第一次使用电子邮件/密码成功登录时请求和检索access tokenrefresh tokenID token

After this successful login, every subsequent login, we want to leverage biometrics (touch/face ID). 成功登录后,每次后续登录,我们都希望利用生物识别技术(触摸/面部识别码)。 My first thought was to store the refreshToken in the Keychain, check for the presence of a refreshToken before forcing a user to input his/her email/pw. 我的第一个想法是将refreshToken存储在Keychain中,在强制用户输入他/她的email / pw之前检查是否存在refreshToken

If a refreshToken exists, then I imagine I would use a call to the token endpoint, using a ?p=refresh_token as opposed to the ?p={INSERT ROPC Policy Name} and if I return a success, then I use Touch/Face ID to login. 如果存在refreshToken ,那么我想我会使用一个调用令牌端点,使用?p=refresh_token而不是?p={INSERT ROPC Policy Name} ,如果我返回成功,那么我使用Touch / Face要登录的ID。

The other thought I had was to just use the token ID to authenticate. 另一个想法是只使用令牌ID进行身份验证。

Thus my question is two-fold: 因此,我的问题是双重的:

  1. What is the better practice - for iOS native application to use a refresh token or an ID token. 更好的做法是什么 - 对于iOS本机应用程序来说,使用刷新令牌或ID令牌。

  2. I've tried using the refresh token, swapping out the {ROPC Policy Name} parameter with ?p=refresh_token , but every time I tried configuring the request, I get an error saying "The request body must contain the following parameter: 'grant_type'" I've added "refresh_token" as the key grant_type 's value and that error still comes up. 我尝试使用刷新令牌,用?p=refresh_token交换{ROPC Policy Name}参数,但每次我尝试配置请求时,都会收到错误消息"The request body must contain the following parameter: 'grant_type'"我添加了”refresh_token“作为关键grant_type的值,并且该错误仍然出现。 -- Why is that and how do I get around it if refresh token grant_type is better. - 为什么这样,如果刷新令牌grant_type更好,我该如何解决它。

You are correct. 你是对的。

You can save the refresh token to the key chain and protect the use of this refresh token with Face or Touch ID. 您可以将刷新令牌保存到密钥链,并使用Face或Touch ID保护此刷新令牌的使用。

The "Redeem a refresh token" section of the "Configure the resource owner password credentials flow in Azure AD B2C" document describes how to redeem a refresh token that was issued for a resource owner policy: 在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}

Thanks @Chris Padgett. 谢谢@Chris Padgett。 I was able to get it up and running with AppAuth using a slightly modified request. 我能够使用略微修改的请求启动并运行AppAuth。 This was my code. 这是我的代码。

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...
    }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM