Name: Auth0.Android
Owner: Auth0
Description: Android toolkit for Auth0 API
Created: 2016-06-29 17:50:35.0
Updated: 2018-05-23 07:39:03.0
Pushed: 2018-05-03 22:45:31.0
Homepage: https://auth0.com
Size: 941
Language: Java
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Android java toolkit for Auth0 API
Android API version 15 or newer
Auth0.android is available through Gradle. To install it, simply add the following line to your build.gradle
file:
ndencies {
compile 'com.auth0.android:auth0:1.12.2'
Open your app's AndroidManifest.xml
file and add the following permission.
s-permission android:name="android.permission.INTERNET" />
First create an instance of Auth0
with your Application information
0 account = new Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}");
Alternatively, you can save your Application information in the strings.xml
file using the following names:
ources>
<string name="com_auth0_client_id">YOUR_CLIENT_ID</string>
<string name="com_auth0_domain">YOUR_DOMAIN</string>
sources>
And then create a new Auth0 instance by passing an Android Context:
0 account = new Auth0(context);
It is strongly encouraged that this SDK be used in OIDC Conformant mode. When this mode is enabled, it will force the SDK to use Auth0's current authentication pipeline and will prevent it from reaching legacy endpoints. By default is false
0 account = new Auth0("{YOUR_CLIENT_ID}", "{YOUR_DOMAIN}");
nfigure the account in OIDC conformant mode
unt.setOIDCConformant(true);
e the account in the API clients
Passwordless authentication cannot be used with this flag set to true
. For more information, please see the OIDC adoption guide.
First go to Auth0 Dashboard and go to your application's settings. Make sure you have in Allowed Callback URLs a URL with the following format:
s://{YOUR_AUTH0_DOMAIN}/android/{YOUR_APP_PACKAGE_NAME}/callback
Remember to replace {YOUR_APP_PACKAGE_NAME}
with your actual application's package name, available in your app/build.gradle
file as the applicationId
value.
Next, define the Manifest Placeholders for the Auth0 Domain and Scheme which are going to be used internally by the library to register an intent-filter. Go to your application's build.gradle
file and add the manifestPlaceholders
line as shown below:
y plugin: 'com.android.application'
oid {
compileSdkVersion 25
defaultConfig {
applicationId "com.auth0.samples"
minSdkVersion 15
targetSdkVersion 25
//...
//---> Add the next line
manifestPlaceholders = [auth0Domain: "@string/com_auth0_domain", auth0Scheme: "https"]
//<---
}
//...
It's a good practice to define reusable resources like @string/com_auth0_domain
but you can also hard code the value in the file. The scheme value can be either https
or a custom one. Read this section to learn more.
Alternatively, you can declare the RedirectActivity
in the AndroidManifest.xml
file with your own intent-filter so it overrides the library's default. If you do this then the manifestPlaceholders
don't need to be set as long as the activity contains the tools:node="replace"
like in the snippet below.
In your manifest inside your application's tag add the RedirectActivity
declaration:
ifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="your.app.package">
<application android:theme="@style/AppTheme">
<!-- ... -->
<activity
android:name="com.auth0.android.provider.RedirectActivity"
tools:node="replace">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="@string/com_auth0_domain"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="https" />
</intent-filter>
</activity>
<!-- ... -->
</application>
nifest>
If you request a different scheme you must replace the above android:scheme
property value and initialize the provider with the new scheme. Read this section to learn more.
Finally, don't forget to add the internet permission.
s-permission android:name="android.permission.INTERNET" />
In versions 1.8.0 and before you had to define the intent-filter inside your activity to capture the result in the
onNewIntent
method and callWebAuthProvider.resume()
with the received intent. This call is no longer required for versions greater than 1.8.0 as it's now done for you by the library.
Finally, authenticate by showing the Auth0 Universal Login:
uthProvider.init(account)
.start(MainActivity.this, authCallback);
If you've followed the configuration steps, the authentication result will be redirected from the browser to your application and you'll receive it in the Callback.
If you've followed this document configuration steps you've noticed that the default scheme used in the Callback Uri is https
. This works best for Android API 23 or newer if you're using Android App Links, but in previous Android versions this may show the intent chooser dialog prompting the user to chose either your application or the browser. You can change this behaviour by using a custom unique scheme so that the OS opens directly the link with your app.
auth0Scheme
Manifest Placeholder on the app/build.gradle
file or update the intent-filter declaration in the AndroidManifest.xml
to use the new scheme.withScheme()
passing the custom scheme you want to use.uthProvider.init(account)
.withScheme("myapp")
.start(MainActivity.this, authCallback);
uthProvider.init(account)
.withConnection("twitter")
.start(MainActivity.this, authCallback);
Before you can use
Code Grant
in Android, make sure to go to your application's section in dashboard and check in the Settings thatClient Type
isNative
.
uthProvider.init(account)
.useCodeGrant(true)
.start(MainActivity.this, authCallback);
The snippet below requests the “userinfo” audience in order to guarantee OIDC compliant responses from the server. This can also be achieved by flipping the “OIDC Conformant” switch on in the OAuth Advanced Settings of your application. For more information check this documentation.
uthProvider.init(account)
.withAudience("https://{YOUR_AUTH0_DOMAIN}/userinfo")
.start(MainActivity.this, authCallback);
Replace
{YOUR_AUTH0_DOMAIN}
with your actual Auth0 domain (i.e.mytenant.auth0.com
).
uthProvider.init(account)
.withScope("openid profile email")
.start(MainActivity.this, authCallback);
The default scope used is
openid
uthProvider.init(account)
.withConnectionScope("email", "profile", "calendar:read")
.start(MainActivity.this, authCallback);
If the device where the app is running has a Custom Tabs compatible Browser, a Custom Tab will be preferred for the authentication flow. You can customize the Page Title visibility and the Toolbar color by using the CustomTabsOptions
class.
tomTabsOptions options = CustomTabsOptions.newBuilder()
.withToolbarColor(R.color.ct_toolbar_color)
.showTitle(true)
.build();
bAuthProvider.init(account)
.withCustomTabsOptions(options)
.start(MainActivity.this, authCallback);
Check out the Android QuickStart Guide to find out more about the Auth0.Android toolkit and explore our tutorials and sample projects.
The client provides methods to authenticate the user against Auth0 server.
Create a new instance by passing the account:
enticationAPIClient authentication = new AuthenticationAPIClient(account);
If the Auth0
instance wasn't configured as “OIDC conformant”, this call requires the Application to have the Resource Owner Client Grant Type enabled. Check this article to learn how to enable it.
entication
.login("info@auth0.com", "a secret password", "my-database-connection")
.start(new BaseCallback<Credentials>() {
@Override
public void onSuccess(Credentials payload) {
//Logged in!
}
@Override
public void onFailure(AuthenticationException error) {
//Error!
}
});
The default scope used is
openid
This call requires the client to have the MFA Client Grant Type enabled. Check this article to learn how to enable it.
When you sign in to a multifactor authentication enabled connection using the login
method, you receive an error standing that MFA is required for that user along with an mfa_token
value. Use this value to call loginWithOTP
and complete the MFA flow passing the One Time Password from the enrolled MFA code generator app.
entication
.loginWithOTP("the mfa token", "123456")
.start(new BaseCallback<Credentials>() {
@Override
public void onSuccess(Credentials payload) {
//Logged in!
}
@Override
public void onFailure(AuthenticationException error) {
//Error!
}
});
This feature requires your Application to have the Resource Owner Legacy Grant Type enabled. Check this article to learn how to enable it. Note that Passwordless authentication cannot be used with the OIDC Conformant Mode enabled.
Passwordless it's a 2 steps flow:
Step 1: Request the code
entication
.passwordlessWithEmail("info@auth0.com", PasswordlessType.CODE, "my-passwordless-connection")
.start(new BaseCallback<Credentials>() {
@Override
public void onSuccess(Void payload) {
//Code sent!
}
@Override
public void onFailure(AuthenticationException error) {
//Error!
}
});
The default scope used is
openid
Step 2: Input the code
entication
.loginWithEmail("info@auth0.com", "123456", "my-passwordless-connection")
@Override
public void onSuccess(Credentials payload) {
//Logged in!
}
@Override
public void onFailure(AuthenticationException error) {
//Error!
}
});
entication
.signUp("info@auth0.com", "a secret password", "my-database-connection")
.start(new BaseCallback<Credentials>() {
@Override
public void onSuccess(Credentials payload) {
//Signed Up & Logged in!
}
@Override
public void onFailure(AuthenticationException error) {
//Error!
}
});
entication
userInfo("user access_token")
start(new BaseCallback<Credentials>() {
@Override
public void onSuccess(UserProfile payload) {
//Got the profile!
}
@Override
public void onFailure(AuthenticationException error) {
//Error!
}
);
The client provides methods to link and unlink users account.
Create a new instance by passing the account and the primary user token:
0 account = new Auth0("client id", "domain");
sAPIClient users = new UsersAPIClient(account, "api token");
s
.link("primary user id", "secondary user token")
.start(new BaseCallback<List<UserIdentity>>() {
@Override
public void onSuccess(List<UserIdentity> payload) {
//Got the updated identities! Accounts linked.
}
@Override
public void onFailure(Auth0Exception error) {
//Error!
}
});
s
.unlink("primary user id", "secondary user id", "secondary provider")
.start(new BaseCallback<List<UserIdentity>>() {
@Override
public void onSuccess(List<UserIdentity> payload) {
//Got the updated identities! Accounts linked.
}
@Override
public void onFailure(Auth0Exception error) {
//Error!
}
});
s
.getProfile("user id")
.start(new BaseCallback<UserProfile, ManagementException>() {
@Override
public void onSuccess(UserProfile payload) {
//Profile
}
@Override
public void onFailure(ManagementException error) {
//Error!
}
});
String, Object> metadata = new HashMap<>();
data.put("name", Arrays.asList("My", "Name", "Is"));
data.put("phoneNumber", "1234567890");
s
.updateMetadata("user id", metadata)
.start(new BaseCallback<UserProfile, ManagementException>() {
@Override
public void onSuccess(UserProfile payload) {
//Metadata updated
}
@Override
public void onFailure(ManagementException error) {
//Error!
}
});
In all the cases, the
User ID
parameter is the unique identifier of the auth0 account instance. i.e. ingoogle-oauth2|123456789081523216417
it would be the part after the '|' pipe:123456789081523216417
.
This library ships with two additional classes that help you manage the Credentials received during authentication. Depending on the minimum API level that your application is targeting you'd like to use a different implementation.
The basic version supports asking for Credentials
existence, storing them and getting them back. If the credentials have expired and a refresh_token was saved, they are automatically refreshed. The class is called CredentialsManager
and requires at minimum Android API 15.
AuthenticationAPIClient
instance to renew the credentials when they expire and a Storage
object. We provide a SharedPreferencesStorage
class that makes use of SharedPreferences
to create a file in the application's directory with Context.MODE_PRIVATE mode. This implementation is thread safe and can either be obtained through a shared method or on demand.enticationAPIClient authentication = new AuthenticationAPIClient(account);
age storage = new SharedPreferencesStorage(this);
entialsManager manager = new CredentialsManager(authentication, storage);
expires_in
and at least an access_token
or id_token
value. If one of the values is missing when trying to set the credentials, the method will throw a CredentialsManagerException
. If you want the manager to successfully renew the credentials when expired you must also request the offline_access
scope when logging in in order to receive a refresh_token
value along with the rest of the tokens. i.e. Logging in with a database connection and saving the credentials:entication
.login("info@auth0.com", "a secret password", "my-database-connection")
.setScope("openid offline_access")
.start(new BaseCallback<Credentials>() {
@Override
public void onSuccess(Credentials credentials) {
//Save the credentials
manager.saveCredentials(credentials);
}
@Override
public void onFailure(AuthenticationException error) {
//Error!
}
});
hasValidCredentials
method that can let you know in advance if a non-expired token is available without making an additional network call. The same rules of the getCredentials
method apply:ean authenticated = manager.hasValidCredentials();
refresh_token
will be used to attempt to renew them. If the expires_in
or both the access_token
and id_token
values are missing, the method will throw a CredentialsManagerException
. The same will happen if the credentials have expired and there's no refresh_token
available.ger.getCredentials(new BaseCallback<Credentials, CredentialsManagerException>(){
ublic void onSuccess(Credentials credentials){
//Use the Credentials
public void onFailure(CredentialsManagerException error){
//Error!
ger.clearCredentials();
This version expands the minimum version and adds encryption to the data storage. In those devices where a Secure LockScreen has been configured it can require the user authentication before letting them obtain the stored credentials. The class is called SecureCredentialsManager
and requires at minimum Android API 21.
The usage is similar to the previous version, with the slight difference that the manager now requires a valid Context
as shown below:
enticationAPIClient authentication = new AuthenticationAPIClient(account);
age storage = new SharedPreferencesStorage(this);
reCredentialsManager manager = new SecureCredentialsManager(this, authentication, storage);
You can require the user authentication to obtain credentials. This will make the manager prompt the user with the device's configured LockScreen, which they must pass correctly in order to obtain the credentials. This feature is only available on devices where the user has setup a secured LockScreen (PIN, Pattern, Password or Fingerprint).
To enable authentication you must call the requireAuthentication
method passing a valid Activity context, a Request Code that represents the authentication call, and the title and description to display in the LockScreen. As seen in the snippet below, you can leave these last two parameters with null
to use the system default resources.
u might want to define a constant with the Request Code
ate static final int AUTH_REQ_CODE = 11;
ger.requireAuthentication(this, AUTH_REQ_CODE, null, null);
When the above conditions are met and the manager requires the user authentication, it will use the activity context to launch a new activity for result. The outcome of getting approved or rejected by the LockScreen is given back to the activity in the onActivityResult
method, which your activity must override to redirect the data to the manager using the checkAuthenticationResult
method.
rride
ected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (manager.checkAuthenticationResult(requestCode, resultCode)) {
return;
}
super.onActivityResult(requestCode, resultCode, data);
The checkAuthenticationResult
method will continue the retrieval of credentials on a successful authentication, and the decrypted credentials will be delivered to the callback passed on the getCredentials
call.
'InvalidPackage'
considered a warning?When building the project with build
, an error appeared regarding an invalid package
on the okio
dependency. This snippet is in the build.gradle
file so that the build runs fine:
oid {
//...
lintOptions {
warning 'InvalidPackage'
}
ref: https://github.com/square/okio/issues/58#issuecomment-72672263
The rules should be applied automatically if your application is using minifyEnabled = true
. If you want to include them manually check the proguard directory.
By default you should at least use the following files:
proguard-okio.pro
proguard-gson.pro
Auth0 helps you to:
If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.
This project is licensed under the MIT license. See the LICENSE file for more info.