Я использую OKTA для аутентификации в приложении android. Когда я запускаю приложение, если токен имеет значение null, пользователь перенаправляется на страницу аутентификации okta, после того как он вводит свой логин и пароль, обратный вызов Okta возвращает состояние отмены и не удачно В моей учетной записи okta, пользователь полностью аутентифицирован, если я снова запускаю приложение, токен найден, и я вошел в систему, не проходя мимо страницы okta
Это означает, что первая аутентификация работала хорошо, но не не вернуть успех, мне нужно время ожидания? или есть другая проблема
Вот мой код Основная активность
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val auth = AuthenticationFactory(this)
auth.setupCallback({
initialize()
}, this)
auth.signIn(this)
}
AuthenticationFactory
class AuthenticationFactory(context: Context) {
private var config = OIDCConfig.Builder()
.withJsonFile(context, R.raw.okta_oidc_config)
.create()
private var webClient = Okta.WebAuthBuilder()
.withConfig(config)
.withContext(context)
.supportedBrowsers("com.android.chrome", "com.google.android.apps.chrome", "com.google.android.apps.chrome.Main", "com.android.chrome.beta", "com.sec.android.app.sbrowser")
.withTabColor(ColorExtension.PRIMARY)
.setRequireHardwareBackedKeyStore(!isEmulator())
.create()
private val sessionClient: SessionClient by lazy { webClient.sessionClient }
// Public Var
val accessToken: String?
get() = sessionClient.tokens.accessToken
val isAccessTokenExpired: Boolean
get() = sessionClient.tokens.isAccessTokenExpired
// Setup
fun setupCallback(onAuthSuccess: () -> (Unit), activity: Activity) {
val callback = object : ResultCallback<AuthorizationStatus, AuthorizationException> {
override fun onSuccess(status: AuthorizationStatus) {
Log.e("AUTH", "AUTHORIZED")
if (status == AuthorizationStatus.AUTHORIZED) {
Log.e("AUTH", "onOktaLoginSuccess | Launching mainActivityIntent")
onAuthSuccess()
} else if (status == AuthorizationStatus.SIGNED_OUT) {
//this only clears the session.
Log.e("AUTH", "signedOutOfOkta")
onOktaSignOutSuccess()
}
}
override fun onCancel() {
Log.e("AUTH", "CANCELED!")
cancelOkta()
}
override fun onError(msg: String?, error: AuthorizationException?) {
Log.e("AUTH", error?.errorDescription + " onError " + msg, error)
onOktaFailure(error)
}
}
webClient.registerCallback(callback, activity)
}
// RESULTS
fun onOktaSignOutFailure() {
val cancelIntent = Intent(App.context, LogoutCancelActivity::class.java)
cancelIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(App.context, cancelIntent, null)
}
private fun onOktaSignOutSuccess() {
val completionIntent = Intent(App.context, LogoutSuccessActivity::class.java)
completionIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(App.context, completionIntent, null)
}
private fun onOktaFailure(p0: AuthorizationException?) {
Log.d("AUTH", "onOktaFailure | Error: ${p0?.errorDescription ?: ""}")
val cancelIntent = Intent(App.context, LoginCancelActivity::class.java)
cancelIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(App.context, cancelIntent, null)
}
// ACTIONS
fun signIn(activity: Activity) {
Log.e("AUTH", "webClient sign in")
webClient.signIn(activity, null)
}
fun signOutFromOkta(activity: Activity) {
sessionClient.clear()
webClient.signOutOfOkta(activity)
}
suspend fun refreshAccessTokenNonAsync(): Boolean? = suspendCoroutine { cont ->
sessionClient.refreshToken(object : RequestCallback<Tokens, AuthorizationException> {
override fun onSuccess(result: Tokens) { cont.resume(true) }
override fun onError(error: String, exception: AuthorizationException) { cont.resume(false) }
})
}
fun cancelOkta() {
webClient.cancel()
sessionClient.cancel()
val cancelIntent = Intent(App.context, LoginCancelActivity::class.java)
cancelIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(App.context, cancelIntent, null)
}
// COMPANION
companion object {
val shared: AuthenticationFactory
get() = AuthenticationFactory(App.context)
fun isEmulator(): Boolean {
return (Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Google")
|| Build.PRODUCT.contains("sdk_gphone")
|| Build.DEVICE.contains("generic"))
}
}
}