Add end session support by agologan · Pull Request #525 · openid/AppAuth-Android · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions README.md
4 changes: 3 additions & 1 deletion app/README-Okta.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ You can create an Okta developer account at [https://developer.okta.com/](https:
| Setting | Value |
| ------------------- | --------------------------------------------------- |
| Application Name | OpenId Connect App *(must be unique)* |
| Redirect URIs | com.oktapreview.yoursubdomain://callback_url|
| Login redirect URIs | com.oktapreview.yoursubdomain://callback_url|
| Logout redirect URIs| com.oktapreview.yoursubdomain://callback_url|
| Allowed grant types | Authorization Code |

1. Click **Finish** to redirect back to the *General Settings* of your application.
Expand All @@ -27,6 +28,7 @@ You can create an Okta developer account at [https://developer.okta.com/](https:
{
"client_id": "{{YourClientID}}",
"redirect_uri": "com.oktapreview.{{yourOrg}}:/oauth",
"end_session_uri": "com.oktapreview.{{yourOrg}}:/{logoutCallback}",
"authorization_scope": "openid email profile",
"discovery_uri": "https://{{yourOrg}}.okta.com/.well-known/openid-configuration"
}
Expand Down
9 changes: 9 additions & 0 deletions app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ The configuration file MUST contain a JSON object. The following properties can
The value specified here should match the value specified for `appAuthRedirectScheme` in the
`build.gradle` (Module: app), so that the demo app can capture the response.

- `end_sesion_uri` (required): The redirect URI to use for receiving the end session response.
This should be a custom scheme URI (com.example.app:/oauth2redirect/example-provider).
Consult the documentation for your authorization server.

The value specified here should match the value specified for `appAuthRedirectScheme` in the
`build.gradle` (Module: app), so that the demo app can capture the response.

NOTE: Scheme of the URI should be the same as `redirect_uri` but callback should be different.

- `authorization_scope` (required): The scope string to use for the authorization request.
For the purposes of the demo, we recommend the value "openid profile email", though any value
understood by your authorization server can be used.
Expand Down
14 changes: 14 additions & 0 deletions app/java/net/openid/appauthdemo/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ public final class Configuration {
private String mClientId;
private String mScope;
private Uri mRedirectUri;
private Uri mEndSessionUri;
private Uri mDiscoveryUri;
private Uri mAuthEndpointUri;
private Uri mTokenEndpointUri;
private Uri mEndSessionEndpoint;
private Uri mRegistrationEndpointUri;
private Uri mUserInfoEndpointUri;
private boolean mHttpsRequired;
Expand Down Expand Up @@ -141,6 +143,11 @@ public Uri getDiscoveryUri() {
return mDiscoveryUri;
}

@Nullable
public Uri getEndSessionUri() {
return mEndSessionUri;
}

@Nullable
public Uri getAuthEndpointUri() {
return mAuthEndpointUri;
Expand All @@ -151,6 +158,11 @@ public Uri getTokenEndpointUri() {
return mTokenEndpointUri;
}

@Nullable
public Uri getEndSessionEndpoint() {
return mEndSessionEndpoint;
}

@Nullable
public Uri getRegistrationEndpointUri() {
return mRegistrationEndpointUri;
Expand Down Expand Up @@ -195,6 +207,7 @@ private void readConfiguration() throws InvalidConfigurationException {
mClientId = getConfigString("client_id");
mScope = getRequiredConfigString("authorization_scope");
mRedirectUri = getRequiredConfigUri("redirect_uri");
mEndSessionUri = getRequiredConfigUri("end_session_uri");

if (!isRedirectUriRegistered()) {
throw new InvalidConfigurationException(
Expand All @@ -209,6 +222,7 @@ private void readConfiguration() throws InvalidConfigurationException {

mTokenEndpointUri = getRequiredConfigWebUri("token_endpoint_uri");
mUserInfoEndpointUri = getRequiredConfigWebUri("user_info_endpoint_uri");
mEndSessionEndpoint = getRequiredConfigUri("end_session_endpoint");

if (mClientId == null) {
mRegistrationEndpointUri = getRequiredConfigWebUri("registration_endpoint_uri");
Expand Down
1 change: 1 addition & 0 deletions app/java/net/openid/appauthdemo/LoginActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ private void initializeAppAuth() {
AuthorizationServiceConfiguration config = new AuthorizationServiceConfiguration(
mConfiguration.getAuthEndpointUri(),
mConfiguration.getTokenEndpointUri(),
mConfiguration.getEndSessionEndpoint(),
mConfiguration.getRegistrationEndpointUri());

mAuthStateManager.replace(new AuthState(config));
Expand Down
36 changes: 34 additions & 2 deletions app/java/net/openid/appauthdemo/TokenActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package net.openid.appauthdemo;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
Expand All @@ -36,6 +37,7 @@
import net.openid.appauth.AuthorizationService;
import net.openid.appauth.AuthorizationServiceDiscovery;
import net.openid.appauth.ClientAuthentication;
import net.openid.appauth.EndSessionRequest;
import net.openid.appauth.TokenRequest;
import net.openid.appauth.TokenResponse;
import okio.Okio;
Expand Down Expand Up @@ -65,6 +67,8 @@ public class TokenActivity extends AppCompatActivity {

private static final String KEY_USER_INFO = "userInfo";

private static final int END_SESSION_REQUEST_CODE = 911;

private AuthorizationService mAuthService;
private AuthStateManager mStateManager;
private final AtomicReference<JSONObject> mUserInfoJson = new AtomicReference<>();
Expand Down Expand Up @@ -186,7 +190,7 @@ private void displayAuthorized() {

AuthState state = mStateManager.getCurrent();

TextView refreshTokenInfoView = (TextView) findViewById(R.id.refresh_token_info);
TextView refreshTokenInfoView = findViewById(R.id.refresh_token_info);
refreshTokenInfoView.setText((state.getRefreshToken() == null)
? R.string.no_refresh_token_returned
: R.string.refresh_token_returned);
Expand Down Expand Up @@ -230,7 +234,7 @@ private void displayAuthorized() {
viewProfileButton.setOnClickListener((View view) -> fetchUserInfo());
}

((Button)findViewById(R.id.sign_out)).setOnClickListener((View view) -> signOut());
findViewById(R.id.sign_out).setOnClickListener((View view) -> endSession());

View userInfoCard = findViewById(R.id.userinfo_card);
JSONObject userInfo = mUserInfoJson.get();
Expand Down Expand Up @@ -380,6 +384,24 @@ private void fetchUserInfo(String accessToken, String idToken, AuthorizationExce
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == END_SESSION_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
signOut();
finish();
} else {
displayEndSessionCancelled();
}
}

private void displayEndSessionCancelled() {
Snackbar.make(findViewById(R.id.coordinator),
"Sign out canceled",
Snackbar.LENGTH_SHORT)
.show();
}

@MainThread
private void showSnackbar(String message) {
Snackbar.make(findViewById(R.id.coordinator),
Expand All @@ -388,6 +410,16 @@ private void showSnackbar(String message) {
.show();
}

@MainThread
private void endSession() {
Intent endSessionEnten = mAuthService.getEndSessionRequestIntent(
new EndSessionRequest.Builder(
mStateManager.getCurrent().getAuthorizationServiceConfiguration(),
mStateManager.getCurrent().getIdToken(),
mConfiguration.getEndSessionUri()).build());
startActivityForResult(endSessionEnten, END_SESSION_REQUEST_CODE);
}

@MainThread
private void signOut() {
// discard the authorization and token state, but retain the configuration and
Expand Down
1 change: 1 addition & 0 deletions app/res/raw/auth_config.json
Loading