优化appauth登录
This commit is contained in:
parent
f50a15b5ac
commit
04d21c8769
@ -11,15 +11,10 @@ import android.graphics.Bitmap;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
|
||||||
import androidx.annotation.MainThread;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.WorkerThread;
|
|
||||||
import androidx.browser.customtabs.CustomTabsIntent;
|
|
||||||
import androidx.core.app.ActivityOptionsCompat;
|
import androidx.core.app.ActivityOptionsCompat;
|
||||||
|
|
||||||
import com.bytedance.sdk.open.tiktok.TikTokOpenApiFactory;
|
import com.bytedance.sdk.open.tiktok.TikTokOpenApiFactory;
|
||||||
@ -30,6 +25,7 @@ import com.bytedance.sdk.open.tiktok.base.VideoObject;
|
|||||||
import com.bytedance.sdk.open.tiktok.share.Share;
|
import com.bytedance.sdk.open.tiktok.share.Share;
|
||||||
import com.cege.games.release.activity.CustomCaptureActivity;
|
import com.cege.games.release.activity.CustomCaptureActivity;
|
||||||
import com.cege.games.release.activity.WebPageActivity;
|
import com.cege.games.release.activity.WebPageActivity;
|
||||||
|
import com.cege.games.release.appauth.AppAuthSvr;
|
||||||
import com.cege.games.release.apple.AppleLoginActivity;
|
import com.cege.games.release.apple.AppleLoginActivity;
|
||||||
import com.cege.games.release.wallet.WalletUtil;
|
import com.cege.games.release.wallet.WalletUtil;
|
||||||
import com.facebook.AccessToken;
|
import com.facebook.AccessToken;
|
||||||
@ -54,8 +50,6 @@ import com.google.android.gms.tasks.Task;
|
|||||||
import com.google.api.services.drive.DriveScopes;
|
import com.google.api.services.drive.DriveScopes;
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics;
|
import com.google.firebase.analytics.FirebaseAnalytics;
|
||||||
import com.jc.jcfw.JcSDK;
|
import com.jc.jcfw.JcSDK;
|
||||||
import com.jc.jcfw.appauth.AuthStateManager;
|
|
||||||
import com.jc.jcfw.appauth.JConfiguration;
|
|
||||||
import com.jc.jcfw.google.PayClient;
|
import com.jc.jcfw.google.PayClient;
|
||||||
import com.jc.jcfw.util.JsonUtils;
|
import com.jc.jcfw.util.JsonUtils;
|
||||||
import com.king.zxing.CameraScan;
|
import com.king.zxing.CameraScan;
|
||||||
@ -63,22 +57,7 @@ import com.king.zxing.util.CodeUtils;
|
|||||||
import com.king.zxing.util.LogUtils;
|
import com.king.zxing.util.LogUtils;
|
||||||
import com.unity3d.player.UnityPlayerActivity;
|
import com.unity3d.player.UnityPlayerActivity;
|
||||||
|
|
||||||
import net.openid.appauth.AppAuthConfiguration;
|
|
||||||
import net.openid.appauth.AuthState;
|
import net.openid.appauth.AuthState;
|
||||||
import net.openid.appauth.AuthorizationException;
|
|
||||||
import net.openid.appauth.AuthorizationRequest;
|
|
||||||
import net.openid.appauth.AuthorizationResponse;
|
|
||||||
import net.openid.appauth.AuthorizationService;
|
|
||||||
import net.openid.appauth.AuthorizationServiceConfiguration;
|
|
||||||
import net.openid.appauth.ClientAuthentication;
|
|
||||||
import net.openid.appauth.ClientSecretBasic;
|
|
||||||
import net.openid.appauth.RegistrationRequest;
|
|
||||||
import net.openid.appauth.RegistrationResponse;
|
|
||||||
import net.openid.appauth.ResponseTypeValues;
|
|
||||||
import net.openid.appauth.TokenRequest;
|
|
||||||
import net.openid.appauth.TokenResponse;
|
|
||||||
import net.openid.appauth.browser.AnyBrowserMatcher;
|
|
||||||
import net.openid.appauth.browser.BrowserMatcher;
|
|
||||||
|
|
||||||
import org.cocos2dx.lib.Cocos2dxHelper;
|
import org.cocos2dx.lib.Cocos2dxHelper;
|
||||||
import org.cocos2dx.lib.CocosJSHelper;
|
import org.cocos2dx.lib.CocosJSHelper;
|
||||||
@ -86,13 +65,9 @@ import org.json.JSONException;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import pub.devrel.easypermissions.AfterPermissionGranted;
|
import pub.devrel.easypermissions.AfterPermissionGranted;
|
||||||
import pub.devrel.easypermissions.EasyPermissions;
|
import pub.devrel.easypermissions.EasyPermissions;
|
||||||
@ -126,14 +101,9 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
private String mFunID;
|
private String mFunID;
|
||||||
|
|
||||||
// AppAuth
|
// AppAuth
|
||||||
private AuthorizationService mAuthService;
|
private AppAuthSvr mAppAuthSvr;
|
||||||
private AuthStateManager mAuthStateManager;
|
|
||||||
private JConfiguration mConfiguration;
|
|
||||||
private ExecutorService mExecutor;
|
private ExecutorService mExecutor;
|
||||||
private final AtomicReference<String> mClientId = new AtomicReference<>();
|
|
||||||
private final AtomicReference<AuthorizationRequest> mAuthRequest = new AtomicReference<>();
|
|
||||||
private final AtomicReference<CustomTabsIntent> mAuthIntent = new AtomicReference<>();
|
|
||||||
private CountDownLatch mAuthIntentLatch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
private TikTokOpenApi tiktokOpenApi;
|
private TikTokOpenApi tiktokOpenApi;
|
||||||
|
|
||||||
@ -141,9 +111,6 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
return mFunID;
|
return mFunID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private final BrowserMatcher mBrowserMatcher = AnyBrowserMatcher.INSTANCE;
|
|
||||||
|
|
||||||
private GoogleSignInClient mGoogleSignInClient;
|
private GoogleSignInClient mGoogleSignInClient;
|
||||||
// facebook login
|
// facebook login
|
||||||
private CallbackManager mCallbackManager;
|
private CallbackManager mCallbackManager;
|
||||||
@ -152,7 +119,7 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
private AppEventsLogger fbLogger;
|
private AppEventsLogger fbLogger;
|
||||||
private WalletUtil mWalletUtil;
|
private WalletUtil mWalletUtil;
|
||||||
|
|
||||||
private Consumer<String> loginCbAction = null;
|
|
||||||
|
|
||||||
public boolean isGooglePlayServicesAvailable() {
|
public boolean isGooglePlayServicesAvailable() {
|
||||||
return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS;
|
return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS;
|
||||||
@ -180,10 +147,9 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
// end of google sign
|
// end of google sign
|
||||||
|
|
||||||
// begin of google oauth sign
|
// begin of google oauth sign
|
||||||
|
mAppAuthSvr = new AppAuthSvr(this);
|
||||||
mExecutor = Executors.newSingleThreadExecutor();
|
mExecutor = Executors.newSingleThreadExecutor();
|
||||||
mAuthStateManager = AuthStateManager.getInstance(this);
|
mAppAuthSvr.init(mExecutor);
|
||||||
mConfiguration = JConfiguration.getInstance(this);
|
|
||||||
mExecutor.submit(this::initializeAppAuth);
|
|
||||||
// end of google oauth sign
|
// end of google oauth sign
|
||||||
|
|
||||||
// begin of facebook login
|
// begin of facebook login
|
||||||
@ -217,22 +183,7 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
parsePhoto(data);
|
parsePhoto(data);
|
||||||
break;
|
break;
|
||||||
case RC_AUTH:
|
case RC_AUTH:
|
||||||
AuthorizationResponse response = AuthorizationResponse.fromIntent(data);
|
mAppAuthSvr.parseLoginResult(data);
|
||||||
AuthorizationException ex = AuthorizationException.fromIntent(data);
|
|
||||||
if (response != null || ex != null) {
|
|
||||||
mAuthStateManager.updateAfterAuthorization(response, ex);
|
|
||||||
}
|
|
||||||
if (response != null && response.authorizationCode != null) {
|
|
||||||
// authorization code exchange is required
|
|
||||||
mAuthStateManager.updateAfterAuthorization(response, ex);
|
|
||||||
exchangeAuthorizationCode(response);
|
|
||||||
} else if (ex != null) {
|
|
||||||
Log.i(TAG, "Authorization flow failed: " + ex.getMessage());
|
|
||||||
JcSDK.nativeCb(mFunID, "Authorization flow failed: " + ex.getMessage(), null);
|
|
||||||
} else {
|
|
||||||
Log.i(TAG, "No authorization state retained - reauthorization required");
|
|
||||||
JcSDK.nativeCb(mFunID, "No authorization state retained - reauthorization required", null);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case RC_SIGN_IN:
|
case RC_SIGN_IN:
|
||||||
handleSignInResult(GoogleSignIn.getSignedInAccountFromIntent(data));
|
handleSignInResult(GoogleSignIn.getSignedInAccountFromIntent(data));
|
||||||
@ -427,18 +378,20 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "no gms, use app auth");
|
Log.d(TAG, "no gms, use app auth");
|
||||||
AuthState state = mAuthStateManager.getCurrent();
|
AuthState state = mAppAuthSvr.getCurrentState();
|
||||||
if (state.isAuthorized()) {
|
if (state.isAuthorized()) {
|
||||||
if (state.getNeedsTokenRefresh()) {
|
if (state.getNeedsTokenRefresh()) {
|
||||||
Log.w(TAG, "need refresh accessToken");
|
Log.w(TAG, "need refresh accessToken");
|
||||||
performTokenRequest(state.createTokenRefreshRequest(), this::handleCodeExchangeResponse);
|
mAppAuthSvr.refreshToken(funId, null);
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "already login, accessToken not expired, id token:: " + state.getIdToken());
|
Log.w(TAG, "already login, accessToken not expired, id token:: " + state.getIdToken());
|
||||||
JcSDK.nativeCb(this.mFunID, null, state.getIdToken());
|
JcSDK.nativeCb(this.mFunID, null, state.getIdToken());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "not login");
|
Log.w(TAG, "not login");
|
||||||
mExecutor.submit(this::doAuth);
|
mExecutor.submit(() -> {
|
||||||
|
mAppAuthSvr.doAuth(funId, null);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,271 +419,6 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin of AppAuth
|
|
||||||
/**
|
|
||||||
* Initializes the authorization service configuration if necessary, either from
|
|
||||||
* the local
|
|
||||||
* static values or by retrieving an OpenID discovery document.
|
|
||||||
*/
|
|
||||||
@WorkerThread
|
|
||||||
private void initializeAppAuth() {
|
|
||||||
Log.i(TAG, "Initializing AppAuth");
|
|
||||||
recreateAuthorizationService();
|
|
||||||
|
|
||||||
if (mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration() != null) {
|
|
||||||
// configuration is already created, skip to client initialization
|
|
||||||
Log.i(TAG, "auth config already established");
|
|
||||||
initializeClient();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we are not using discovery, build the authorization service configuration
|
|
||||||
// directly
|
|
||||||
// from the static configuration values.
|
|
||||||
if (mConfiguration.getDiscoveryUri() == null) {
|
|
||||||
Log.i(TAG, "Creating auth config from res/raw/auth_config.json");
|
|
||||||
AuthorizationServiceConfiguration config = new AuthorizationServiceConfiguration(
|
|
||||||
mConfiguration.getAuthEndpointUri(),
|
|
||||||
mConfiguration.getTokenEndpointUri(),
|
|
||||||
mConfiguration.getRegistrationEndpointUri(),
|
|
||||||
mConfiguration.getEndSessionEndpoint());
|
|
||||||
|
|
||||||
mAuthStateManager.replace(new AuthState(config));
|
|
||||||
initializeClient();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// WrongThread inference is incorrect for lambdas
|
|
||||||
// noinspection WrongThread
|
|
||||||
Log.i(TAG, "Retrieving OpenID discovery doc");
|
|
||||||
AuthorizationServiceConfiguration.fetchFromUrl(
|
|
||||||
mConfiguration.getDiscoveryUri(),
|
|
||||||
this::handleConfigurationRetrievalResult,
|
|
||||||
mConfiguration.getConnectionBuilder());
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainThread
|
|
||||||
private void handleConfigurationRetrievalResult(
|
|
||||||
AuthorizationServiceConfiguration config,
|
|
||||||
AuthorizationException ex) {
|
|
||||||
if (config == null) {
|
|
||||||
Log.i(TAG, "Failed to retrieve discovery document", ex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(TAG, "Discovery document retrieved");
|
|
||||||
mAuthStateManager.replace(new AuthState(config));
|
|
||||||
mExecutor.submit(this::initializeClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recreateAuthorizationService() {
|
|
||||||
if (mAuthService != null) {
|
|
||||||
Log.i(TAG, "Discarding existing AuthService instance");
|
|
||||||
mAuthService.dispose();
|
|
||||||
}
|
|
||||||
mAuthService = createAuthorizationService();
|
|
||||||
mAuthRequest.set(null);
|
|
||||||
mAuthIntent.set(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthorizationService createAuthorizationService() {
|
|
||||||
Log.i(TAG, "Creating authorization service");
|
|
||||||
AppAuthConfiguration.Builder builder = new AppAuthConfiguration.Builder();
|
|
||||||
builder.setBrowserMatcher(mBrowserMatcher);
|
|
||||||
builder.setConnectionBuilder(mConfiguration.getConnectionBuilder());
|
|
||||||
|
|
||||||
return new AuthorizationService(this, builder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createAuthRequest(@Nullable String loginHint) {
|
|
||||||
Log.i(TAG, "Creating auth request for login hint: " + loginHint);
|
|
||||||
AuthorizationRequest.Builder authRequestBuilder = new AuthorizationRequest.Builder(
|
|
||||||
mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration(),
|
|
||||||
mClientId.get(),
|
|
||||||
ResponseTypeValues.CODE,
|
|
||||||
mConfiguration.getRedirectUri())
|
|
||||||
// apple need `form_post` when authorization_scope has `name email `
|
|
||||||
// .setResponseMode("form_post")
|
|
||||||
// .setResponseType("code id_token")
|
|
||||||
.setScope(mConfiguration.getScope());
|
|
||||||
if (!TextUtils.isEmpty(loginHint)) {
|
|
||||||
authRequestBuilder.setLoginHint(loginHint);
|
|
||||||
}
|
|
||||||
mAuthRequest.set(authRequestBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void warmUpBrowser() {
|
|
||||||
mAuthIntentLatch = new CountDownLatch(1);
|
|
||||||
mExecutor.execute(() -> {
|
|
||||||
Log.i(TAG, "Warming up browser instance for auth request");
|
|
||||||
Uri uri = mAuthRequest.get().toUri();
|
|
||||||
Log.d(TAG, "URI: " + uri);
|
|
||||||
CustomTabsIntent.Builder intentBuilder = mAuthService.createCustomTabsIntentBuilder(uri);
|
|
||||||
mAuthIntent.set(intentBuilder.build());
|
|
||||||
mAuthIntentLatch.countDown();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainThread
|
|
||||||
private void initializeAuthRequest() {
|
|
||||||
createAuthRequest("");
|
|
||||||
warmUpBrowser();
|
|
||||||
displayAuthOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiates a dynamic registration request if a client ID is not provided by
|
|
||||||
* the static
|
|
||||||
* configuration.
|
|
||||||
*/
|
|
||||||
@WorkerThread
|
|
||||||
private void initializeClient() {
|
|
||||||
if (mConfiguration.getClientId() != null) {
|
|
||||||
Log.i(TAG, "Using static client ID: " + mConfiguration.getClientId());
|
|
||||||
// use a statically configured client ID
|
|
||||||
mClientId.set(mConfiguration.getClientId());
|
|
||||||
runOnUiThread(this::initializeAuthRequest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegistrationResponse lastResponse = mAuthStateManager.getCurrent().getLastRegistrationResponse();
|
|
||||||
if (lastResponse != null) {
|
|
||||||
Log.i(TAG, "Using dynamic client ID: " + lastResponse.clientId);
|
|
||||||
// already dynamically registered a client ID
|
|
||||||
mClientId.set(lastResponse.clientId);
|
|
||||||
runOnUiThread(this::initializeAuthRequest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// WrongThread inference is incorrect for lambdas
|
|
||||||
// noinspection WrongThread
|
|
||||||
Log.i(TAG, "Dynamically registering client");
|
|
||||||
|
|
||||||
RegistrationRequest registrationRequest = new RegistrationRequest.Builder(
|
|
||||||
mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration(),
|
|
||||||
Collections.singletonList(mConfiguration.getRedirectUri()))
|
|
||||||
.setTokenEndpointAuthenticationMethod(ClientSecretBasic.NAME)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
mAuthService.performRegistrationRequest(
|
|
||||||
registrationRequest,
|
|
||||||
this::handleRegistrationResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleRegistrationResponse(
|
|
||||||
RegistrationResponse response,
|
|
||||||
AuthorizationException ex) {
|
|
||||||
mAuthStateManager.updateAfterRegistration(response, ex);
|
|
||||||
if (response == null) {
|
|
||||||
Log.i(TAG, "Failed to dynamically register client", ex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(TAG, "Dynamically registered client: " + response.clientId);
|
|
||||||
mClientId.set(response.clientId);
|
|
||||||
initializeAuthRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void displayAuthOptions() {
|
|
||||||
AuthState state = mAuthStateManager.getCurrent();
|
|
||||||
AuthorizationServiceConfiguration config = state.getAuthorizationServiceConfiguration();
|
|
||||||
|
|
||||||
String authEndpointStr;
|
|
||||||
if (config.discoveryDoc != null) {
|
|
||||||
authEndpointStr = "Discovered auth endpoint: \n";
|
|
||||||
} else {
|
|
||||||
authEndpointStr = "Static auth endpoint: \n";
|
|
||||||
}
|
|
||||||
authEndpointStr += config.authorizationEndpoint;
|
|
||||||
Log.i(TAG, authEndpointStr);
|
|
||||||
|
|
||||||
String clientIdStr;
|
|
||||||
if (state.getLastRegistrationResponse() != null) {
|
|
||||||
clientIdStr = "Dynamic client ID: \n";
|
|
||||||
} else {
|
|
||||||
clientIdStr = "Static client ID: \n";
|
|
||||||
}
|
|
||||||
clientIdStr += mClientId;
|
|
||||||
Log.i(TAG, clientIdStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the authorization request, using the browser selected in the
|
|
||||||
* spinner,
|
|
||||||
* and a user-provided `login_hint` if available.
|
|
||||||
*/
|
|
||||||
@WorkerThread
|
|
||||||
private void doAuth() {
|
|
||||||
try {
|
|
||||||
mAuthIntentLatch.await();
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
Log.w(TAG, "Interrupted while waiting for auth intent");
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent intent = mAuthService.getAuthorizationRequestIntent(
|
|
||||||
mAuthRequest.get(),
|
|
||||||
mAuthIntent.get());
|
|
||||||
startActivityForResult(intent, RC_AUTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainThread
|
|
||||||
private void exchangeAuthorizationCode(AuthorizationResponse authorizationResponse) {
|
|
||||||
Log.d(TAG, "Exchanging authorization code");
|
|
||||||
performTokenRequest(
|
|
||||||
authorizationResponse.createTokenExchangeRequest(),
|
|
||||||
this::handleCodeExchangeResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainThread
|
|
||||||
private void performTokenRequest(
|
|
||||||
TokenRequest request,
|
|
||||||
AuthorizationService.TokenResponseCallback callback) {
|
|
||||||
ClientAuthentication clientAuthentication;
|
|
||||||
try {
|
|
||||||
clientAuthentication = mAuthStateManager.getCurrent().getClientAuthentication();
|
|
||||||
} catch (ClientAuthentication.UnsupportedAuthenticationMethod ex) {
|
|
||||||
Log.d(TAG, "Token request cannot be made, client authentication for the token "
|
|
||||||
+ "endpoint could not be constructed (%s)", ex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mAuthService.performTokenRequest(
|
|
||||||
request,
|
|
||||||
clientAuthentication,
|
|
||||||
callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkAuthStateAndCB() {
|
|
||||||
AuthState state = mAuthStateManager.getCurrent();
|
|
||||||
Log.d(TAG, "login success, auth state: " + state.isAuthorized());
|
|
||||||
Log.d(TAG, "id token : " + state.getIdToken());
|
|
||||||
Log.d(TAG, "access token: " + state.getAccessToken());
|
|
||||||
Log.d(TAG, "refresh token: " + state.getRefreshToken());
|
|
||||||
mAuthStateManager.replace(state);
|
|
||||||
if (loginCbAction != null) {
|
|
||||||
mExecutor.submit(() -> {
|
|
||||||
loginCbAction.accept("success");
|
|
||||||
loginCbAction = null;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
JcSDK.nativeCb(this.mFunID, null, state.getIdToken());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@WorkerThread
|
|
||||||
private void handleCodeExchangeResponse(
|
|
||||||
@Nullable TokenResponse tokenResponse,
|
|
||||||
@Nullable AuthorizationException authException) {
|
|
||||||
mAuthStateManager.updateAfterTokenResponse(tokenResponse, authException);
|
|
||||||
if (!mAuthStateManager.getCurrent().isAuthorized()) {
|
|
||||||
final String message = "Authorization Code exchange failed: "
|
|
||||||
+ ((authException != null) ? authException.error : "");
|
|
||||||
Log.d(TAG, message);
|
|
||||||
JcSDK.nativeCb(mFunID, message, null);
|
|
||||||
} else {
|
|
||||||
checkAuthStateAndCB();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sign with tiktok
|
// sign with tiktok
|
||||||
public void signWithTiktok(String funId) {
|
public void signWithTiktok(String funId) {
|
||||||
@ -909,24 +597,23 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
mWalletUtil.uploadCfgWithGPS(_result -> {});
|
mWalletUtil.uploadCfgWithGPS(_result -> {});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AuthState state = mAuthStateManager.getCurrent();
|
AuthState state = mAppAuthSvr.getCurrentState();
|
||||||
if (state.isAuthorized()) {
|
if (state.isAuthorized()) {
|
||||||
if (state.getNeedsTokenRefresh()) {
|
if (state.getNeedsTokenRefresh()) {
|
||||||
Log.d(TAG, "need refresh accessToken");
|
Log.d(TAG, "need refresh accessToken");
|
||||||
loginCbAction = _result -> {
|
mAppAuthSvr.refreshToken(funID, _result -> {
|
||||||
mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{});
|
mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{});
|
||||||
};
|
});
|
||||||
performTokenRequest(state.createTokenRefreshRequest(),
|
|
||||||
this::handleCodeExchangeResponse);
|
|
||||||
} else {
|
} else {
|
||||||
mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{});
|
mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "not login");
|
Log.w(TAG, "not login");
|
||||||
loginCbAction = _result -> {
|
mExecutor.submit(() -> {
|
||||||
mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{});
|
mAppAuthSvr.doAuth(funID, _result -> {
|
||||||
};
|
mWalletUtil.uploadCfgWithApi(state.getAccessToken(), _r->{});
|
||||||
mExecutor.submit(this::doAuth);
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -960,20 +647,18 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!mWalletUtil.localCfgExists(account)) {
|
if (!mWalletUtil.localCfgExists(account)) {
|
||||||
AuthState state = mAuthStateManager.getCurrent();
|
AuthState state = mAppAuthSvr.getCurrentState();
|
||||||
// 1. check whether the google account has been logged in, this situation occurs when non-google login
|
// 1. check whether the google account has been logged in, this situation occurs when non-google login
|
||||||
// 2. check if already had permission of drive appdata, add permission of drive appdata to auth_config
|
// 2. check if already had permission of drive appdata, add permission of drive appdata to auth_config
|
||||||
// 3. check if need refresh access token
|
// 3. check if need refresh access token
|
||||||
if (state.isAuthorized()) {
|
if (state.isAuthorized()) {
|
||||||
if (state.getNeedsTokenRefresh()) {
|
if (state.getNeedsTokenRefresh()) {
|
||||||
Log.d(TAG, "need refresh accessToken");
|
Log.d(TAG, "need refresh accessToken");
|
||||||
loginCbAction = _result -> {
|
mAppAuthSvr.refreshToken(funID, _result -> {
|
||||||
mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> {
|
mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> {
|
||||||
mWalletUtil.getPassLocal();
|
mWalletUtil.getPassLocal();
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
performTokenRequest(state.createTokenRefreshRequest(),
|
|
||||||
this::handleCodeExchangeResponse);
|
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "access token no need refresh");
|
Log.d(TAG, "access token no need refresh");
|
||||||
mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> {
|
mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> {
|
||||||
@ -982,12 +667,13 @@ public class MainActivity extends UnityPlayerActivity
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "not login");
|
Log.w(TAG, "not login");
|
||||||
loginCbAction = _result -> {
|
mExecutor.submit(() -> {
|
||||||
mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> {
|
mAppAuthSvr.doAuth(funID, _result -> {
|
||||||
mWalletUtil.getPassLocal();
|
mWalletUtil.downloadCfgWithApi(state.getAccessToken(), _file -> {
|
||||||
|
mWalletUtil.getPassLocal();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
mExecutor.submit(this::doAuth);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mWalletUtil.getPassLocal();
|
mWalletUtil.getPassLocal();
|
||||||
|
394
app/src/com/cege/games/release/appauth/AppAuthSvr.java
Normal file
394
app/src/com/cege/games/release/appauth/AppAuthSvr.java
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
package com.cege.games.release.appauth;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.MainThread;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
|
import androidx.browser.customtabs.CustomTabsIntent;
|
||||||
|
|
||||||
|
import com.jc.jcfw.JcSDK;
|
||||||
|
import com.jc.jcfw.appauth.AuthStateManager;
|
||||||
|
import com.jc.jcfw.appauth.JConfiguration;
|
||||||
|
import com.jc.jcfw.util.ThreadUtils;
|
||||||
|
|
||||||
|
import net.openid.appauth.AppAuthConfiguration;
|
||||||
|
import net.openid.appauth.AuthState;
|
||||||
|
import net.openid.appauth.AuthorizationException;
|
||||||
|
import net.openid.appauth.AuthorizationRequest;
|
||||||
|
import net.openid.appauth.AuthorizationResponse;
|
||||||
|
import net.openid.appauth.AuthorizationService;
|
||||||
|
import net.openid.appauth.AuthorizationServiceConfiguration;
|
||||||
|
import net.openid.appauth.ClientAuthentication;
|
||||||
|
import net.openid.appauth.ClientSecretBasic;
|
||||||
|
import net.openid.appauth.RegistrationRequest;
|
||||||
|
import net.openid.appauth.RegistrationResponse;
|
||||||
|
import net.openid.appauth.ResponseTypeValues;
|
||||||
|
import net.openid.appauth.TokenRequest;
|
||||||
|
import net.openid.appauth.TokenResponse;
|
||||||
|
import net.openid.appauth.browser.AnyBrowserMatcher;
|
||||||
|
import net.openid.appauth.browser.BrowserMatcher;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class AppAuthSvr {
|
||||||
|
private final String TAG = getClass().getSimpleName();
|
||||||
|
private final Activity activity;
|
||||||
|
private AuthorizationService mAuthService;
|
||||||
|
private AuthStateManager mAuthStateManager;
|
||||||
|
private JConfiguration mConfiguration;
|
||||||
|
private ExecutorService mExecutor;
|
||||||
|
private final AtomicReference<String> mClientId = new AtomicReference<>();
|
||||||
|
private final AtomicReference<AuthorizationRequest> mAuthRequest = new AtomicReference<>();
|
||||||
|
private final AtomicReference<CustomTabsIntent> mAuthIntent = new AtomicReference<>();
|
||||||
|
private CountDownLatch mAuthIntentLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
private String mFunID;
|
||||||
|
|
||||||
|
private static final int RC_AUTH = 0X04;
|
||||||
|
|
||||||
|
private Consumer<String> loginCbAction = null;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final BrowserMatcher mBrowserMatcher = AnyBrowserMatcher.INSTANCE;
|
||||||
|
|
||||||
|
public AppAuthSvr(Activity activity) {
|
||||||
|
this.activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(ExecutorService executorService) {
|
||||||
|
mExecutor = executorService;
|
||||||
|
mAuthStateManager = AuthStateManager.getInstance(activity);
|
||||||
|
mConfiguration = JConfiguration.getInstance(activity);
|
||||||
|
mExecutor.submit(this::initializeAppAuth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFunID(String funID) {
|
||||||
|
this.mFunID = funID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoginCbAction(Consumer<String> func) {
|
||||||
|
this.loginCbAction = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthState getCurrentState() {
|
||||||
|
return mAuthStateManager.getCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the authorization request, using the browser selected in the
|
||||||
|
* spinner,
|
||||||
|
* and a user-provided `login_hint` if available.
|
||||||
|
*/
|
||||||
|
@WorkerThread
|
||||||
|
public void doAuth(String funID, Consumer<String> func) {
|
||||||
|
this.mFunID = funID;
|
||||||
|
this.loginCbAction = func;
|
||||||
|
try {
|
||||||
|
mAuthIntentLatch.await();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Log.w(TAG, "Interrupted while waiting for auth intent");
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent intent = mAuthService.getAuthorizationRequestIntent(
|
||||||
|
mAuthRequest.get(),
|
||||||
|
mAuthIntent.get());
|
||||||
|
activity.startActivityForResult(intent, RC_AUTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parseLoginResult(@NonNull Intent data) {
|
||||||
|
AuthorizationResponse response = AuthorizationResponse.fromIntent(data);
|
||||||
|
AuthorizationException ex = AuthorizationException.fromIntent(data);
|
||||||
|
if (response != null || ex != null) {
|
||||||
|
mAuthStateManager.updateAfterAuthorization(response, ex);
|
||||||
|
}
|
||||||
|
if (response != null && response.authorizationCode != null) {
|
||||||
|
// authorization code exchange is required
|
||||||
|
mAuthStateManager.updateAfterAuthorization(response, ex);
|
||||||
|
exchangeAuthorizationCode(response);
|
||||||
|
} else if (ex != null) {
|
||||||
|
Log.i(TAG, "Authorization flow failed: " + ex.getMessage());
|
||||||
|
errorCB("Authorization flow failed: " + ex.getMessage());
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "No authorization state retained - reauthorization required");
|
||||||
|
errorCB("No authorization state retained - reauthorization required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refreshToken(String funID, Consumer<String> func) {
|
||||||
|
this.mFunID = funID;
|
||||||
|
this.loginCbAction = func;
|
||||||
|
AuthState state = getCurrentState();
|
||||||
|
performTokenRequest(state.createTokenRefreshRequest(), this::handleCodeExchangeResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the authorization service configuration if necessary, either from
|
||||||
|
* the local
|
||||||
|
* static values or by retrieving an OpenID discovery document.
|
||||||
|
*/
|
||||||
|
@WorkerThread
|
||||||
|
private void initializeAppAuth() {
|
||||||
|
Log.i(TAG, "Initializing AppAuth");
|
||||||
|
recreateAuthorizationService();
|
||||||
|
|
||||||
|
if (mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration() != null) {
|
||||||
|
// configuration is already created, skip to client initialization
|
||||||
|
Log.i(TAG, "auth config already established");
|
||||||
|
initializeClient();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we are not using discovery, build the authorization service configuration
|
||||||
|
// directly
|
||||||
|
// from the static configuration values.
|
||||||
|
if (mConfiguration.getDiscoveryUri() == null) {
|
||||||
|
Log.i(TAG, "Creating auth config from res/raw/auth_config.json");
|
||||||
|
AuthorizationServiceConfiguration config = new AuthorizationServiceConfiguration(
|
||||||
|
mConfiguration.getAuthEndpointUri(),
|
||||||
|
mConfiguration.getTokenEndpointUri(),
|
||||||
|
mConfiguration.getRegistrationEndpointUri(),
|
||||||
|
mConfiguration.getEndSessionEndpoint());
|
||||||
|
|
||||||
|
mAuthStateManager.replace(new AuthState(config));
|
||||||
|
initializeClient();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrongThread inference is incorrect for lambdas
|
||||||
|
// noinspection WrongThread
|
||||||
|
Log.i(TAG, "Retrieving OpenID discovery doc");
|
||||||
|
AuthorizationServiceConfiguration.fetchFromUrl(
|
||||||
|
mConfiguration.getDiscoveryUri(),
|
||||||
|
this::handleConfigurationRetrievalResult,
|
||||||
|
mConfiguration.getConnectionBuilder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainThread
|
||||||
|
private void handleConfigurationRetrievalResult(
|
||||||
|
AuthorizationServiceConfiguration config,
|
||||||
|
AuthorizationException ex) {
|
||||||
|
if (config == null) {
|
||||||
|
Log.i(TAG, "Failed to retrieve discovery document", ex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "Discovery document retrieved");
|
||||||
|
mAuthStateManager.replace(new AuthState(config));
|
||||||
|
mExecutor.submit(this::initializeClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recreateAuthorizationService() {
|
||||||
|
if (mAuthService != null) {
|
||||||
|
Log.i(TAG, "Discarding existing AuthService instance");
|
||||||
|
mAuthService.dispose();
|
||||||
|
}
|
||||||
|
mAuthService = createAuthorizationService();
|
||||||
|
mAuthRequest.set(null);
|
||||||
|
mAuthIntent.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthorizationService createAuthorizationService() {
|
||||||
|
Log.i(TAG, "Creating authorization service");
|
||||||
|
AppAuthConfiguration.Builder builder = new AppAuthConfiguration.Builder();
|
||||||
|
builder.setBrowserMatcher(mBrowserMatcher);
|
||||||
|
builder.setConnectionBuilder(mConfiguration.getConnectionBuilder());
|
||||||
|
|
||||||
|
return new AuthorizationService(activity, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createAuthRequest(@Nullable String loginHint) {
|
||||||
|
Log.i(TAG, "Creating auth request for login hint: " + loginHint);
|
||||||
|
AuthorizationRequest.Builder authRequestBuilder = new AuthorizationRequest.Builder(
|
||||||
|
mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration(),
|
||||||
|
mClientId.get(),
|
||||||
|
ResponseTypeValues.CODE,
|
||||||
|
mConfiguration.getRedirectUri())
|
||||||
|
// apple need `form_post` when authorization_scope has `name email `
|
||||||
|
// .setResponseMode("form_post")
|
||||||
|
// .setResponseType("code id_token")
|
||||||
|
.setScope(mConfiguration.getScope());
|
||||||
|
if (!TextUtils.isEmpty(loginHint)) {
|
||||||
|
authRequestBuilder.setLoginHint(loginHint);
|
||||||
|
}
|
||||||
|
mAuthRequest.set(authRequestBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void warmUpBrowser() {
|
||||||
|
mAuthIntentLatch = new CountDownLatch(1);
|
||||||
|
mExecutor.execute(() -> {
|
||||||
|
Log.i(TAG, "Warming up browser instance for auth request");
|
||||||
|
Uri uri = mAuthRequest.get().toUri();
|
||||||
|
Log.d(TAG, "URI: " + uri);
|
||||||
|
CustomTabsIntent.Builder intentBuilder = mAuthService.createCustomTabsIntentBuilder(uri);
|
||||||
|
mAuthIntent.set(intentBuilder.build());
|
||||||
|
mAuthIntentLatch.countDown();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainThread
|
||||||
|
private void initializeAuthRequest() {
|
||||||
|
createAuthRequest("");
|
||||||
|
warmUpBrowser();
|
||||||
|
displayAuthOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates a dynamic registration request if a client ID is not provided by
|
||||||
|
* the static
|
||||||
|
* configuration.
|
||||||
|
*/
|
||||||
|
@WorkerThread
|
||||||
|
private void initializeClient() {
|
||||||
|
if (mConfiguration.getClientId() != null) {
|
||||||
|
Log.i(TAG, "Using static client ID: " + mConfiguration.getClientId());
|
||||||
|
// use a statically configured client ID
|
||||||
|
mClientId.set(mConfiguration.getClientId());
|
||||||
|
ThreadUtils.runInMain(this::initializeAuthRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegistrationResponse lastResponse = mAuthStateManager.getCurrent().getLastRegistrationResponse();
|
||||||
|
if (lastResponse != null) {
|
||||||
|
Log.i(TAG, "Using dynamic client ID: " + lastResponse.clientId);
|
||||||
|
// already dynamically registered a client ID
|
||||||
|
mClientId.set(lastResponse.clientId);
|
||||||
|
ThreadUtils.runInMain(this::initializeAuthRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrongThread inference is incorrect for lambdas
|
||||||
|
// noinspection WrongThread
|
||||||
|
Log.i(TAG, "Dynamically registering client");
|
||||||
|
|
||||||
|
RegistrationRequest registrationRequest = new RegistrationRequest.Builder(
|
||||||
|
mAuthStateManager.getCurrent().getAuthorizationServiceConfiguration(),
|
||||||
|
Collections.singletonList(mConfiguration.getRedirectUri()))
|
||||||
|
.setTokenEndpointAuthenticationMethod(ClientSecretBasic.NAME)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
mAuthService.performRegistrationRequest(
|
||||||
|
registrationRequest,
|
||||||
|
this::handleRegistrationResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRegistrationResponse(
|
||||||
|
RegistrationResponse response,
|
||||||
|
AuthorizationException ex) {
|
||||||
|
mAuthStateManager.updateAfterRegistration(response, ex);
|
||||||
|
if (response == null) {
|
||||||
|
Log.i(TAG, "Failed to dynamically register client", ex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "Dynamically registered client: " + response.clientId);
|
||||||
|
mClientId.set(response.clientId);
|
||||||
|
initializeAuthRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayAuthOptions() {
|
||||||
|
AuthState state = mAuthStateManager.getCurrent();
|
||||||
|
AuthorizationServiceConfiguration config = state.getAuthorizationServiceConfiguration();
|
||||||
|
|
||||||
|
String authEndpointStr;
|
||||||
|
if (config.discoveryDoc != null) {
|
||||||
|
authEndpointStr = "Discovered auth endpoint: \n";
|
||||||
|
} else {
|
||||||
|
authEndpointStr = "Static auth endpoint: \n";
|
||||||
|
}
|
||||||
|
authEndpointStr += config.authorizationEndpoint;
|
||||||
|
Log.i(TAG, authEndpointStr);
|
||||||
|
|
||||||
|
String clientIdStr;
|
||||||
|
if (state.getLastRegistrationResponse() != null) {
|
||||||
|
clientIdStr = "Dynamic client ID: \n";
|
||||||
|
} else {
|
||||||
|
clientIdStr = "Static client ID: \n";
|
||||||
|
}
|
||||||
|
clientIdStr += mClientId;
|
||||||
|
Log.i(TAG, clientIdStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainThread
|
||||||
|
private void exchangeAuthorizationCode(AuthorizationResponse authorizationResponse) {
|
||||||
|
Log.d(TAG, "Exchanging authorization code");
|
||||||
|
performTokenRequest(
|
||||||
|
authorizationResponse.createTokenExchangeRequest(),
|
||||||
|
this::handleCodeExchangeResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainThread
|
||||||
|
private void performTokenRequest(
|
||||||
|
TokenRequest request,
|
||||||
|
AuthorizationService.TokenResponseCallback callback) {
|
||||||
|
ClientAuthentication clientAuthentication;
|
||||||
|
try {
|
||||||
|
clientAuthentication = mAuthStateManager.getCurrent().getClientAuthentication();
|
||||||
|
} catch (ClientAuthentication.UnsupportedAuthenticationMethod ex) {
|
||||||
|
Log.d(TAG, "Token request cannot be made, client authentication for the token "
|
||||||
|
+ "endpoint could not be constructed (%s)", ex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAuthService.performTokenRequest(
|
||||||
|
request,
|
||||||
|
clientAuthentication,
|
||||||
|
callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
private void handleCodeExchangeResponse(
|
||||||
|
@Nullable TokenResponse tokenResponse,
|
||||||
|
@Nullable AuthorizationException authException) {
|
||||||
|
mAuthStateManager.updateAfterTokenResponse(tokenResponse, authException);
|
||||||
|
if (!mAuthStateManager.getCurrent().isAuthorized()) {
|
||||||
|
final String message = "Authorization Code exchange failed: "
|
||||||
|
+ ((authException != null) ? authException.error : "");
|
||||||
|
Log.d(TAG, message);
|
||||||
|
errorCB(message);
|
||||||
|
} else {
|
||||||
|
checkAuthStateAndCB();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAuthStateAndCB() {
|
||||||
|
AuthState state = mAuthStateManager.getCurrent();
|
||||||
|
Log.d(TAG, "login success, auth state: " + state.isAuthorized());
|
||||||
|
Log.d(TAG, "id token : " + state.getIdToken());
|
||||||
|
Log.d(TAG, "access token: " + state.getAccessToken());
|
||||||
|
Log.d(TAG, "refresh token: " + state.getRefreshToken());
|
||||||
|
mAuthStateManager.replace(state);
|
||||||
|
if (loginCbAction != null) {
|
||||||
|
mExecutor.submit(() -> {
|
||||||
|
loginCbAction.accept("success");
|
||||||
|
clearParams();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
successCB(state.getIdToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void clearParams() {
|
||||||
|
this.mFunID = null;
|
||||||
|
this.loginCbAction = null;
|
||||||
|
}
|
||||||
|
public void errorCB(String msg) {
|
||||||
|
JcSDK.nativeCb(mFunID, msg, null);
|
||||||
|
clearParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void successCB(String dataStr) {
|
||||||
|
JcSDK.nativeCb(mFunID, null, dataStr);
|
||||||
|
clearParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user