Android oneDrive 集成(二)-- 单租户账号集成
Android oneDrive 集成(三)– 使用Postman测试Graph API
微软的MSAL平台有多种租户模式,本篇文章将介绍单租户的接入方式。
AzureADMyOrg:仅限应用注册的组织目录中的帐户(单租户) |
注意⚠️:本篇文章仅适用于单租户,因为MSAL对不同的租户有不同的接入方式。
一、配置权限
默认情况下,aure平台只会给你分配用户读取权限,如果你需要读写onedrive的文件,还需要配置文件读写权限。
找到Files权限组,根据你的需要,配置你需要的权限。
二、 导入android MSAL库
App中
依赖中添加:
// api 30以上版本使用,否则无法编译成功,没到api30不要使用这个 |
如果无法成功添加依赖,可以尝试添加maven仓库
allprojects { |
2.1 在raw中增加配置
创建名为auth_config_single_account.json
的文件,这是单用户的,里面输入
{ |
这个便是MSAL配置中的生成的东西
2.2 在清单中配置以下代码
<!--Intent filter to capture System Browser or Authenticator calling back to our app after sign-in--> |
三、代码集成
如下图所示,如果已经登陆过了,sdk会自动保存cookies信息到本地,如果本地没有cookie,则需要调用登陆接口跳转微软登陆界面进行登陆。
如果本地有cookie信息,需要通过本地的cookie信息获取到请求的token。
注意⚠️:如果是跳转登陆并且登陆成功后,是不需要重新获取token的。
3.1 初始化
private fun initOneDrive() { |
3.2 账户登陆
检查本地是否有cookie信息
/**
* 加载用户,没有登陆过,则需要重新登陆
*/
private fun loadAccount() {
if (!this::oneDriveApp.isInitialized) {
Log.e(TAG, "还没有初始化sdk")
return
}
oneDriveApp.getCurrentAccountAsync(object : CurrentAccountCallback {
override fun onAccountLoaded(activeAccount: IAccount?) {
if (activeAccount == null) {
Log.w(TAG, "用户还没有登陆")
login()
} else {
Log.w(TAG, "已经登陆过,自动登陆,开始获取token")
getTokenByAccountInfo(activeAccount)
}
}
override fun onAccountChanged(
priorAccount: IAccount?,
currentAccount: IAccount?
) {
Log.w(TAG, "账号已却换,重新获取token")
if (currentAccount == null){
Log.e(TAG, "当前账户为空")
return
}
getTokenByAccountInfo(currentAccount)
}
override fun onError(exception: MsalException) {
exception.printStackTrace()
}
})
}登陆(如果登陆成功,token会同步返回,不需要再调用接口获取token)
private fun login() {
oneDriveApp.signIn(this, "", getScopes(), object : AuthenticationCallback {
override fun onSuccess(authenticationResult: IAuthenticationResult?) {
authInfo = authenticationResult
MSAL.updateAuthInfo(authInfo)
Toast.makeText(this@OneDriveActivity, "登陆成功", Toast.LENGTH_SHORT)
.show()
Log.d(TAG, "登陆成功")
}
override fun onError(exception: MsalException?) {
Toast.makeText(this@OneDriveActivity, "登陆失败", Toast.LENGTH_SHORT)
.show()
Log.d(TAG, "登陆失败")
exception?.printStackTrace()
}
override fun onCancel() {
Log.d(TAG, "取消登陆")
Toast.makeText(this@OneDriveActivity, "登陆取消", Toast.LENGTH_SHORT)
.show()
}
})
}通过cookie获取token
/**
* 根据用户信息获取token
*/
private fun getTokenByAccountInfo(account: IAccount) {
oneDriveApp.acquireTokenSilentAsync(getScopes(), account.authority, object : SilentAuthenticationCallback {
override fun onSuccess(authenticationResult: IAuthenticationResult?) {
Log.d(TAG, "获取token成功")
authInfo = authenticationResult
MSAL.updateAuthInfo(authInfo)
}
override fun onError(exception: MsalException) {
exception.printStackTrace()
Toast.makeText(this@OneDriveActivity, "获取token失败", Toast.LENGTH_SHORT).show()
}
})
}
注意⚠️:getScopes() 为你的接口访问权限范围,根据在后台配置的权限进行填写便可。
3.3 调用api
oneDrive 的sdk并没有直接调用接口的方法,需要用户自己请求MSAL
的webApi接口实现自己的功能。像普通的http请求接口便可。
/** |
注意:没个接口都需要在header中设置token
headers.put["Authorization"] = "${authResult.getAccessToken()}" |
X 常见问题
x.1 Manifest merger failed with multiple errors, see logs
错误信息:
[com.microsoft.identity:common:3.0.9] /Users/aria/.gradle/caches/transforms-2/files-2.1/9bbd0210b395b52a878222653b1cfa37/jetified-common-3.0.9/AndroidManifest.xml:20:9-59 Error: |
原因:
你的api版本没有到30,你却使用了implementation 'com.microsoft.identity.client:msal:2.+'
版本的库
解决:
1、升级到api30
2、使用低版本的库
implementation 'com.microsoft.identity.client:msal:1.6.+' |
x.2 AccountMode in configuration is not set to single.
错误信息:
com.microsoft.identity.client.exception.MsalClientException: AccountMode in configuration is not set to single. Cannot initialize single account PublicClientApplication. |
原因:
你的auth_config_single_account.json
是单账号模式的,因此需要在json文件中指定用户模式。
解决:
在auth_config_single_account.json
文件中添加"account_mode" : "SINGLE"
x.2 只能使用手机号登陆,不能使用邮箱登陆
原因:
指定了Tenant_id租户id。
解决:
auth_config_single_account.json
移除"tenant_id": "consumers"
工程地址
AriaLyy/KeepassA: Android Keepass Software based on Keepass database (github.com)
参考地址
Android oneDrive 集成(二)-- 单租户账号集成
https://www.laoyuyu.me/2021/02/25/android/Android_OneDrive_2/