【发布时间】:2020-12-02 12:22:36
【问题描述】:
我正在尝试在 Android 中实现 MSAL,以便使用他们的 Microsoft 凭据登录用户。 在全新安装时,我第一次能够获取令牌,并进一步使用它来访问 Microsoft Graph API。
由于 MSAL 令牌的过期时间默认为 1 小时,如果我在 1 小时后尝试重新启动应用程序,我将面临令牌身份验证异常。
现在我被困在如何再次刷新令牌上?
在 MSAL 中,我遵循了示例,但没有提到使用 Android SDK 刷新令牌 [我们可以使用 API 调用来获取和刷新令牌,但我没有使用 API 方法,我正在使用 SDK处理所有流程。]
我现在正在努力解决这个问题。
private val AUTHORITY = "https://login.microsoftonline.com/common"
private var mSingleAccountApp: ISingleAccountPublicClientApplication? = null
private var mActiveAccount: MultiTenantAccount? = null
fun startTokenProcess(
activity: LoginActivity,
preferenceManager: PreferenceManager
) {
this.mActivity = activity
this.mPreferences = preferenceManager
mSingleAccountApp = null
// Creates a PublicClientApplication object with res/raw/auth_config.json
PublicClientApplication.createSingleAccountPublicClientApplication(activity,
R.raw.auth_config,
object : IPublicClientApplication.ISingleAccountApplicationCreatedListener {
override fun onCreated(application: ISingleAccountPublicClientApplication?) {
// initialization of ISingleAccountPublicClientApplication object
mSingleAccountApp = application
// check for existence of any account linked in cache
mSingleAccountApp?.getCurrentAccountAsync(object :
ISingleAccountPublicClientApplication.CurrentAccountCallback {
override fun onAccountLoaded(activeAccount: IAccount?) {
if (activeAccount == null) {
// nothing found
// start new interactive signin
mSingleAccountApp?.signIn(mActivity, "", getScopes(),
object : AuthenticationCallback {
override fun onSuccess(authenticationResult: IAuthenticationResult?) {
mActiveAccount =
authenticationResult?.account as MultiTenantAccount?
// save access token in SP
authenticationResult?.accessToken?.let {
mPreferences.putString(
KEY_ACCESS_TOKEN,
it
)
}
callGraphAPI(authenticationResult?.accessToken)
}
override fun onCancel() {
Timber.d("Canceled")
}
override fun onError(exception: MsalException?) {
Timber.d(exception?.errorCode)
}
})
} else {
// Founded an valid account in cache
// get account token from SP, call Graph API
// todo: check if access token expired ? ask for new token, clear SP
mActiveAccount = activeAccount as MultiTenantAccount?
val accessToken = mPreferences.getString(KEY_ACCESS_TOKEN)
if (accessToken != null) {
callGraphAPI(accessToken)
}
}
}
override fun onAccountChanged(
priorAccount: IAccount?,
currentAccount: IAccount?
) {
Timber.d("Founded an account $priorAccount")
Timber.d("Founded an account $currentAccount")
}
override fun onError(exception: MsalException) {
Timber.e(exception)
}
})
}
override fun onError(exception: MsalException?) {
Timber.e(exception)
}
})
}
我尝试再次以静默交互方式获取令牌,但没有成功。
默默地:
mSingleAccountApp?.acquireTokenSilentAsync(getScopes(), AUTHORITY, getAuthSilentCallback())
private fun getAuthSilentCallback(): SilentAuthenticationCallback {
return object : SilentAuthenticationCallback {
override fun onSuccess(authenticationResult: IAuthenticationResult) {
Timber.d("Successfully authenticated")
/* Successfully got a token, use it to call a protected resource - MSGraph */
callGraphAPI(authenticationResult?.accessToken)
}
override fun onError(exception: MsalException) {
/* Failed to acquireToken */
Timber.e("Authentication failed: $exception")
if (exception is MsalClientException) {
Timber.e("Exception inside MSAL, more info inside MsalError.java ")
} else if (exception is MsalServiceException) {
Timber.e("Exception when communicating with the STS, likely config issue")
} else if (exception is MsalUiRequiredException) {
Timber.e("Tokens expired or no session, retry with interactive")
}
}
}
}
或
交互式:
if (activeAccount == null) {
mSingleAccountApp?.signIn(mActivity, "", getScopes(),
object : AuthenticationCallback {
override fun onSuccess(authenticationResult: IAuthenticationResult?) {
mActiveAccount =
authenticationResult?.account as MultiTenantAccount?
// save access token in SP
authenticationResult?.accessToken?.let {
mPreferences.putString(
KEY_ACCESS_TOKEN,
it
)
}
callGraphAPI(authenticationResult?.accessToken)
}
override fun onCancel() {
Timber.d("Canceled")
}
override fun onError(exception: MsalException?) {
Timber.d(exception?.errorCode)
}
})
}
编辑 1:
我得到的例外:
CoreHttpProvider[sendRequestInternal] - 414Graph service exception Error code: InvalidAuthenticationToken
CoreHttpProvider[sendRequestInternal] - 414Error message: Access token has expired.
CoreHttpProvider[sendRequestInternal] - 414SdkVersion : graph-java/v1.9.0
CoreHttpProvider[sendRequestInternal] - 414Authorization : Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI[...]
CoreHttpProvider[sendRequestInternal] - 414Graph service exception Error code: InvalidAuthenticationToken
Throwable detail: com.microsoft.graph.http.GraphServiceException: Error code: InvalidAuthenticationToken
Error message: Access token has expired.
当我重新尝试静默获取令牌时,出现以下异常:
l$getAuthSilentCallback: Authentication failed: com.microsoft.identity.client.exception.MsalServiceException: AADSTS700016: Application with identifier 'Some_ID' was not found in the directory 'Some_ID'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.
Trace ID: 'Some_ID'
Correlation ID: 'Some_ID'
Timestamp: 2020-08-15 06:06:11Z
getAuthSilentCallback: Exception when communicating with the STS, likely config issue
编辑 2 根据我收到的有关配置问题的例外情况,我遇到了这个问题,它与我正在使用的权威 URL 有关。 msal-client-application-configuration
【问题讨论】:
标签: android azure microsoft-graph-api access-token msal