简体   繁体   中英

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. 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:

  1. What is the better practice - for iOS native application to use a refresh token or an ID token.

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

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