I'm developing an iOS app, utilizing the ROPC flow with AADB2C as the backend endpoints supporting this. 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.
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.
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.
The other thought I had was to just use the token ID to authenticate.
Thus my question is two-fold:
What is the better practice - for iOS native application to use a refresh token or an ID token.
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. -- Why is that and how do I get around it if refresh token grant_type is better.
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.
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:
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. I was able to get it up and running with AppAuth using a slightly modified request. 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...
}
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.