Reputation: 804
I need to add OAuth2 authorization in my app. I have only client-id, client-secret and username(email). I need to get token. Can you give me some advise on how to do that? Library or example code?
Upvotes: 8
Views: 18050
Reputation: 3739
You can use AppAuth to do a OAuth2 authorization.
See https://github.com/openid/AppAuth-Android for a example.
The following is a shortend version of the AppAuth documentation.
Overview
It is recommended that native apps use the authorization code flow.
This flow is effectively composed of four stages:
1. Create authorization service configuration
First, create a configuration of the authorization service, which will be used in stage two and three.
AuthorizationServiceConfiguration mServiceConfiguration =
new AuthorizationServiceConfiguration(
Uri.parse("https://example.com/authorize"), // Authorization endpoint
Uri.parse("https://example.com/token")); // Token endpoint
ClientAuthentication mClientAuthentication =
new ClientSecretBasic("my-client-secret"); // Client secret
(Static client secrets aren't recommended in native apps.)
2. Request authorization and obtain authorization code
To receive the authorization callback define following activity in your manifest file. (You don't need to implement this activity. This activity will act like a proxy for your authorization request.)
<activity
android:name="net.openid.appauth.RedirectUriReceiverActivity"
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:scheme="com.example"/> <!-- Redirect URI scheme -->
</intent-filter>
</activity>
Build and execute the authorization request.
private void authorize() {
AuthorizationRequest authRequest = new AuthorizationRequest.Builder(
mServiceConfiguration,
"my-client-id", // Client ID
ResponseTypeValues.CODE,
Uri.parse("com.example://oauth-callback") // Redirect URI
).build();
AuthorizationService service = new AuthorizationService(this);
Intent intent = service.getAuthorizationRequestIntent(authRequest);
startActivityForResult(intent, REQUEST_CODE_AUTH);
}
Handle the authorization response.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode != REQUEST_CODE_AUTH) {
return;
}
AuthorizationResponse authResponse = AuthorizationResponse.fromIntent(intent);
AuthorizationException authException = AuthorizationException.fromIntent(intent);
mAuthState = new AuthState(authResponse, authException);
// Handle authorization response error here
retrieveTokens(authResponse);
}
3. Exchange the authorization code
private void retrieveTokens(AuthorizationResponse authResponse) {
TokenRequest tokenRequest = response.createTokenExchangeRequest();
AuthorizationService service = new AuthorizationService(this);
service.performTokenRequest(request, mClientAuthentication,
new AuthorizationService.TokenResponseCallback() {
@Override
public void onTokenRequestCompleted(TokenResponse tokenResponse,
AuthorizationException tokenException) {
mAuthState.update(tokenResponse, tokenException);
// Handle token response error here
persistAuthState(mAuthState);
}
});
}
After the token retrieval was completed successfully, persist AuthState
so you can reuse it at the next app (re)start.
4. Access protected resource service
Use performActionWithFreshTokens
to execute the API call with a fresh access token. (It will automatically ensure that the tokens are fresh and refresh them when needed.)
private void prepareApiCall() {
AuthorizationService service = new AuthorizationService(this);
mAuthState.performActionWithFreshTokens(service, mClientAuthentication,
new AuthState.AuthStateAction() {
@Override
public void execute(String accessToken, String idToken,
AuthorizationException authException) {
// Handle token refresh error here
executeApiCall(accessToken);
}
});
}
Execute the API call. (The AsyncTask
is just use for simplicity. It might not be the best solution to execute the API call.)
private void executeApiCall(String accessToken) {
new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://example.com/api/...") // API URL
.addHeader("Authorization",
String.format("Bearer %s", params[0]))
.build();
try {
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception e) {
// Handle API error here
}
}
@Override
protected void onPostExecute(String response) {
...
}
}.execute(accessToken);
}
Upvotes: 15