From da46fdcfdfa1b2fb0cc35a6c97aa1a744e172320 Mon Sep 17 00:00:00 2001 From: Rajdeep Nanua Date: Mon, 29 Jan 2024 09:48:27 -0500 Subject: [PATCH 1/3] Add state parameter to AuthorizationCodeFlow.start --- oauth2/api/oauth2.api | 4 ++-- oauth2/src/main/java/com/okta/oauth2/AuthorizationCodeFlow.kt | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/oauth2/api/oauth2.api b/oauth2/api/oauth2.api index 315f0e29..5c5c2b29 100644 --- a/oauth2/api/oauth2.api +++ b/oauth2/api/oauth2.api @@ -2,8 +2,8 @@ public final class com/okta/oauth2/AuthorizationCodeFlow { public static final field Companion Lcom/okta/oauth2/AuthorizationCodeFlow$Companion; public synthetic fun (Lcom/okta/authfoundation/client/OidcClient;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun resume (Landroid/net/Uri;Lcom/okta/oauth2/AuthorizationCodeFlow$Context;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public final fun start (Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun start$default (Lcom/okta/oauth2/AuthorizationCodeFlow;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public final fun start (Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun start$default (Lcom/okta/oauth2/AuthorizationCodeFlow;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; } public final class com/okta/oauth2/AuthorizationCodeFlow$Companion { diff --git a/oauth2/src/main/java/com/okta/oauth2/AuthorizationCodeFlow.kt b/oauth2/src/main/java/com/okta/oauth2/AuthorizationCodeFlow.kt index 797a4a28..99621666 100644 --- a/oauth2/src/main/java/com/okta/oauth2/AuthorizationCodeFlow.kt +++ b/oauth2/src/main/java/com/okta/oauth2/AuthorizationCodeFlow.kt @@ -107,11 +107,12 @@ class AuthorizationCodeFlow private constructor( redirectUrl: String, extraRequestParameters: Map = emptyMap(), scope: String = oidcClient.configuration.defaultScope, + state: String = UUID.randomUUID().toString() ): OidcClientResult { return start( redirectUrl = redirectUrl, codeVerifier = PkceGenerator.codeVerifier(), - state = UUID.randomUUID().toString(), + state = state, nonce = UUID.randomUUID().toString(), extraRequestParameters = extraRequestParameters, scope = scope From 4c0062ee80b575e8a738346ce64b331b608d1dc9 Mon Sep 17 00:00:00 2001 From: Rajdeep Nanua Date: Wed, 31 Jan 2024 09:56:25 -0500 Subject: [PATCH 2/3] Load DT cookie lazily to avoid clients crashing when using initialize in Jetpack startup --- .../okta/authfoundation/client/DeviceTokenCookieJar.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/auth-foundation/src/main/java/com/okta/authfoundation/client/DeviceTokenCookieJar.kt b/auth-foundation/src/main/java/com/okta/authfoundation/client/DeviceTokenCookieJar.kt index c519f0df..dc52d9da 100644 --- a/auth-foundation/src/main/java/com/okta/authfoundation/client/DeviceTokenCookieJar.kt +++ b/auth-foundation/src/main/java/com/okta/authfoundation/client/DeviceTokenCookieJar.kt @@ -23,10 +23,12 @@ import kotlin.time.Duration.Companion.seconds class DeviceTokenCookieJar(private val oidcClock: OidcClock) : CookieJar { private val savedCookiesCache = mutableMapOf>() - private val deviceTokenCookieBuilder = Cookie.Builder() - .name("DT") - .value(DeviceTokenProvider.deviceToken) - .secure() + private val deviceTokenCookieBuilder by lazy { + Cookie.Builder() + .name("DT") + .value(DeviceTokenProvider.deviceToken) + .secure() + } override fun loadForRequest(url: HttpUrl): List { val deviceTokenCookie = deviceTokenCookieBuilder.domain(url.host).build() From 8876a8b87d84adc9a9aa6692c0a358db7f100a35 Mon Sep 17 00:00:00 2001 From: Rajdeep Nanua Date: Wed, 31 Jan 2024 09:59:39 -0500 Subject: [PATCH 3/3] Attempt recovering DeviceTokenProvider during SharedPreferences crash --- .../client/DeviceTokenProvider.kt | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/auth-foundation/src/main/java/com/okta/authfoundation/client/DeviceTokenProvider.kt b/auth-foundation/src/main/java/com/okta/authfoundation/client/DeviceTokenProvider.kt index 88f2be97..5bf13821 100644 --- a/auth-foundation/src/main/java/com/okta/authfoundation/client/DeviceTokenProvider.kt +++ b/auth-foundation/src/main/java/com/okta/authfoundation/client/DeviceTokenProvider.kt @@ -16,12 +16,13 @@ package com.okta.authfoundation.client import android.content.Context +import android.content.SharedPreferences import androidx.annotation.VisibleForTesting import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKeys import java.util.UUID -class DeviceTokenProvider private constructor(appContext: Context) { +class DeviceTokenProvider private constructor(private val appContext: Context) { internal companion object { private const val FILE_NAME = "com.okta.authfoundation.device_token_storage" @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @@ -43,14 +44,26 @@ class DeviceTokenProvider private constructor(appContext: Context) { private val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) + private fun createSharedPreferences(): SharedPreferences { + return EncryptedSharedPreferences.create( + FILE_NAME, + masterKeyAlias, + appContext, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM + ) + } + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - internal val sharedPrefs = EncryptedSharedPreferences.create( - FILE_NAME, - masterKeyAlias, - appContext, - EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, - EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM - ) + internal val sharedPrefs: SharedPreferences by lazy { + try { + createSharedPreferences() + } catch (e: Exception) { + val sharedPreferences = appContext.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE) + sharedPreferences.edit().clear().commit() + createSharedPreferences() + } + } private val sharedPrefsEditor = sharedPrefs.edit()