Skip to content

Commit 8e71558

Browse files
authored
Merge pull request #139 from okta/custom-config-browser-flag
Custom configuration option. Browser flag with match all option.
2 parents 2b43178 + 83de8fe commit 8e71558

20 files changed

Lines changed: 618 additions & 60 deletions

README.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ webClient.registerCallback(new ResultCallback<AuthorizationStatus, Authorization
131131

132132
The `client` can now be used to authenticate users and authorize access.
133133

134-
**Note**: `.well-known/openid-configuration` or `.well-known/oauth-authorization-server` will be appended to your `discoveryUri` if it is missing.
134+
**Note**: `.well-known/openid-configuration` will be appended to your `discoveryUri` if it is missing.
135135

136-
- `discoveryUri` is: `https://{yourOktaDomain}/oauth2/${authServerId}` then `.well-known/oauth-authorization-server` is added.
136+
- `discoveryUri` is: `https://{yourOktaDomain}/oauth2/${authServerId}` then `.well-known/openid-configuration` is added.
137137
- `discoveryUri` is: `https://{yourOktaDomain}` then `.well-known/openid-configuration` is added.
138-
- `discoveryUri` is: `https://{yourOktaDomain}/oauth2/default` then `.well-known/oauth-authorization-server` is added.
138+
- `discoveryUri` is: `https://{yourOktaDomain}/oauth2/default` then `.well-known/openid-configuration` is added.
139139
- `discoveryUri` is: `https://{yourOktaDomain}/oauth2/${authServerId}/.well-known/openid-configuration` nothing is added.
140140
- `discoveryUri` is: `https://{yourOktaDomain}/oauth2/${authServerId}/.well-known/oauth-authorization-server` nothing is added.
141141

@@ -171,6 +171,26 @@ OIDCConfig config = new OIDCConfig.Builder()
171171
.withJsonFile(this, R.raw.okta_oidc_config)
172172
.create();
173173
```
174+
## Configuration without discoveryUri
175+
176+
It is recommended to use `discoveryUri` to retrieve your authorization providers configuration.
177+
But if your provider does not have a `discoveryUri` you can provide the URIs to the endpoints
178+
yourself like the following:
179+
180+
```java
181+
CustomConfiguration config = new CustomConfiguration.Builder()
182+
.tokenEndpoint("{yourTokenEndpoint}")
183+
.authorizationEndpoint("{yourAuthorizeEndpoint}")
184+
.create();
185+
186+
mOidcConfig = new OIDCConfig.Builder()
187+
.clientId(BuildConfig.CLIENT_ID)
188+
.redirectUri(BuildConfig.REDIRECT_URI)
189+
.endSessionRedirectUri(BuildConfig.END_SESSION_URI)
190+
.scopes(BuildConfig.SCOPES)
191+
.customConfiguration(config)
192+
.create();
193+
```
174194

175195
**Note**: To receive a [refresh_token](https://developer.okta.com/docs/guides/refresh-tokens/overview/), you must include the `offline_access` scope.
176196

app/build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ android {
5151
dependencies {
5252
implementation project(':library')
5353
implementation 'androidx.fragment:fragment:' + rootProject.androidxLibVersion
54-
implementation 'androidx.annotation:annotation:' + rootProject.androidxLibVersion
55-
implementation 'androidx.appcompat:appcompat:' + rootProject.androidxLibVersion
54+
implementation 'androidx.annotation:annotation:' + rootProject.appcompatVersion
55+
implementation 'androidx.appcompat:appcompat:' + rootProject.appcompatVersion
5656
implementation 'androidx.security:security-crypto:' + rootProject.securityVersion
5757

5858
implementation "com.google.android.material:material:1.0.0"
59-
implementation 'androidx.biometric:biometric:1.0.0'
59+
implementation 'androidx.biometric:biometric:1.0.1'
6060
implementation 'com.okta.authn.sdk:okta-authn-sdk-api:1.0.0'
6161
implementation('com.okta.authn.sdk:okta-authn-sdk-impl:1.0.0') {
6262
exclude group: 'com.okta.sdk', module: 'okta-sdk-httpclient'
@@ -69,7 +69,7 @@ dependencies {
6969
// Assertions
7070
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
7171
androidTestImplementation 'androidx.test.ext:truth:1.2.0'
72-
androidTestImplementation 'com.google.truth:truth:1.0'
72+
androidTestImplementation 'com.google.truth:truth:1.0.1'
7373

7474
// AndroidJUnitRunner and JUnit Rules
7575
androidTestImplementation 'androidx.test:runner:1.2.0'
@@ -86,7 +86,7 @@ dependencies {
8686
androidTestImplementation 'androidx.test.uiautomator:uiautomator:' + rootProject.uiautomatorVersion
8787
androidTestImplementation 'org.hamcrest:hamcrest-integration:1.3'
8888

89-
androidTestImplementation 'com.github.tomakehurst:wiremock-standalone:2.24.1'
89+
androidTestImplementation 'com.github.tomakehurst:wiremock-standalone:2.25.1'
9090

9191
androidTestImplementation "io.jsonwebtoken:jjwt-api:${rootProject.jsonWebTokenVersion}"
9292
androidTestImplementation "io.jsonwebtoken:jjwt-impl:${rootProject.jsonWebTokenVersion}"

app/src/androidTest/java/com/okta/oidc/example/EncryptionTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ public void setUp() {
6262
public void checkHardwareKeystore() {
6363
boolean hardwareBacked = mEncryptionManager.isHardwareBackedKeyStore();
6464
if (SampleActivity.isEmulator()) {
65-
// Starting from API 26, isHardwareBackedKeyStore on emulator return true
66-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
65+
//API 26, isHardwareBackedKeyStore on emulator return true
66+
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.O) {
6767
assertFalse(hardwareBacked);
6868
} else {
6969
assertTrue(hardwareBacked);

build.gradle

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ buildscript {
99
}
1010
}
1111
dependencies {
12-
classpath 'com.android.tools.build:gradle:3.5.2'
12+
classpath 'com.android.tools.build:gradle:3.5.3'
1313
classpath 'org.owasp:dependency-check-gradle:5.2.2'
1414
// NOTE: Do not place your application dependencies here; they belong
1515
// in the individual module build.gradle files
@@ -42,23 +42,23 @@ ext {
4242
minSdkVersion = 19
4343
compileSdkVersion = 29
4444
buildToolsVersion = "29.0.2"
45-
browserVersion = '1.0.0'
46-
appcompatVersion = '1.0.0'
45+
browserVersion = '1.2.0'
46+
appcompatVersion = '1.1.0'
4747
// SDK dependency versions
4848
bintrayVersion = "1.8.4"
4949
gradlePluginVersion = "1.5"
50-
gsonVersion = "2.8.5"
50+
gsonVersion = "2.8.6"
5151

5252
// Test dependency versions
53-
junitVersion = "4.12"
53+
junitVersion = '4.13'
5454
mockitoVersion = "2.13.0"
55-
robolectricVersion = '4.3'
56-
okhttpVersion = '4.2.0'
55+
robolectricVersion = '4.3.1'
56+
okhttpVersion = '4.3.1'
5757
jsonWebTokenVersion = '0.10.7'
58-
assertjCoreVersion = '3.13.2'
58+
assertjCoreVersion = '3.14.0'
5959
assertjVersion = "1.2.0"
6060

61-
androidxLibVersion = "1.1.0"
61+
androidxLibVersion = "1.2.0"
6262
espressoVersion = "3.2.0"
6363
uiautomatorVersion = "2.2.0"
6464
securityVersion = "1.0.0-alpha02"

library/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ dependencies {
6363
implementation "com.google.code.gson:gson:${rootProject.gsonVersion}"
6464
implementation "androidx.browser:browser:${rootProject.browserVersion}"
6565
implementation "androidx.fragment:fragment:${rootProject.androidxLibVersion}"
66-
implementation "androidx.core:core:${rootProject.androidxLibVersion}"
66+
implementation "androidx.core:core:${rootProject.appcompatVersion}"
6767
testImplementation "com.squareup.okhttp3:okhttp-tls:${rootProject.okhttpVersion}"
6868
testImplementation "io.jsonwebtoken:jjwt-jackson:${rootProject.jsonWebTokenVersion}"
6969
testImplementation("io.jsonwebtoken:jjwt-orgjson:${rootProject.jsonWebTokenVersion}") {
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/*
2+
* Copyright (c) 2020, Okta, Inc. and/or its affiliates. All rights reserved.
3+
* The Okta software accompanied by this notice is provided pursuant to the Apache License,
4+
* Version 2.0 (the "License.")
5+
*
6+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
*
12+
* See the License for the specific language governing permissions and limitations under the
13+
* License.
14+
*/
15+
16+
package com.okta.oidc;
17+
18+
import android.text.TextUtils;
19+
20+
import androidx.annotation.NonNull;
21+
22+
/**
23+
* Used for authorization servers that does not provide a discovery endpoint.
24+
* It is recommended to use {@link com.okta.oidc.OIDCConfig.Builder#discoveryUri(String)}
25+
* to fetch the Open ID provider configuration instead.
26+
*
27+
* @see "OpenID provider issuer discovery <https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery"
28+
*/
29+
@SuppressWarnings("unused")
30+
public class CustomConfiguration {
31+
private String mAuthorizationEndpoint;
32+
private String mTokenEndpoint;
33+
private String mUserInfoEndpoint;
34+
private String mJwksUri;
35+
private String mRegistrationEndpoint;
36+
private String mIntrospectionEndpoint;
37+
private String mRevocationEndpoint;
38+
private String mEndSessionEndpoint;
39+
40+
/**
41+
* Gets authorization endpoint.
42+
*
43+
* @return the authorization endpoint
44+
*/
45+
public String getAuthorizationEndpoint() {
46+
return mAuthorizationEndpoint;
47+
}
48+
49+
/**
50+
* Gets token endpoint.
51+
*
52+
* @return the token endpoint
53+
*/
54+
public String getTokenEndpoint() {
55+
return mTokenEndpoint;
56+
}
57+
58+
/**
59+
* Gets user info endpoint.
60+
*
61+
* @return the user info endpoint
62+
*/
63+
public String getUserInfoEndpoint() {
64+
return mUserInfoEndpoint;
65+
}
66+
67+
/**
68+
* Gets jwks uri.
69+
*
70+
* @return the jwks uri
71+
*/
72+
public String getJwksUri() {
73+
return mJwksUri;
74+
}
75+
76+
/**
77+
* Gets registration endpoint.
78+
*
79+
* @return the registration endpoint
80+
*/
81+
public String getRegistrationEndpoint() {
82+
return mRegistrationEndpoint;
83+
}
84+
85+
/**
86+
* Gets introspection endpoint.
87+
*
88+
* @return the introspection endpoint
89+
*/
90+
public String getIntrospectionEndpoint() {
91+
return mIntrospectionEndpoint;
92+
}
93+
94+
/**
95+
* Gets revocation endpoint.
96+
*
97+
* @return the revocation endpoint
98+
*/
99+
public String getRevocationEndpoint() {
100+
return mRevocationEndpoint;
101+
}
102+
103+
/**
104+
* Gets end session endpoint.
105+
*
106+
* @return the end session endpoint
107+
*/
108+
public String getEndSessionEndpoint() {
109+
return mEndSessionEndpoint;
110+
}
111+
112+
private CustomConfiguration() {
113+
}
114+
115+
/**
116+
* The CustomConfiguration Builder for setting endpoints for Okta OpenID provider.
117+
*
118+
* @see "OpenID Connect & OAuth 2.0 API <https://developer.okta.com/docs/reference/api/oidc/#endpoints"
119+
*/
120+
public static class Builder {
121+
private CustomConfiguration mConfiguration;
122+
123+
/**
124+
* Instantiates a new Builder for CustomConfiguration.
125+
*/
126+
public Builder() {
127+
mConfiguration = new CustomConfiguration();
128+
}
129+
130+
/**
131+
* Required authorization endpoint.
132+
*
133+
* @param authorizationEndpoint the authorization endpoint
134+
* @return the builder
135+
*/
136+
public Builder authorizationEndpoint(@NonNull String authorizationEndpoint) {
137+
mConfiguration.mAuthorizationEndpoint = authorizationEndpoint;
138+
return this;
139+
}
140+
141+
/**
142+
* Required token endpoint.
143+
*
144+
* @param tokenEndpoint the token endpoint
145+
* @return the builder
146+
*/
147+
public Builder tokenEndpoint(@NonNull String tokenEndpoint) {
148+
mConfiguration.mTokenEndpoint = tokenEndpoint;
149+
return this;
150+
}
151+
152+
/**
153+
* Optional user info endpoint.
154+
*
155+
* @param userInfoEndpoint the user info endpoint
156+
* @return the builder
157+
*/
158+
public Builder userInfoEndpoint(@NonNull String userInfoEndpoint) {
159+
mConfiguration.mUserInfoEndpoint = userInfoEndpoint;
160+
return this;
161+
}
162+
163+
/**
164+
* Optional Jwks uri.
165+
*
166+
* @param jwksUri the jwks uri
167+
* @return the builder
168+
*/
169+
public Builder jwksUri(@NonNull String jwksUri) {
170+
mConfiguration.mJwksUri = jwksUri;
171+
return this;
172+
}
173+
174+
/**
175+
* Optional registration endpoint.
176+
*
177+
* @param registrationEndpoint the registration endpoint
178+
* @return the builder
179+
*/
180+
public Builder registrationEndpoint(@NonNull String registrationEndpoint) {
181+
mConfiguration.mRegistrationEndpoint = registrationEndpoint;
182+
return this;
183+
}
184+
185+
/**
186+
* Optional introspection endpoint.
187+
*
188+
* @param introspectionEndpoint the introspection endpoint
189+
* @return the builder
190+
*/
191+
public Builder introspectionEndpoint(@NonNull String introspectionEndpoint) {
192+
mConfiguration.mIntrospectionEndpoint = introspectionEndpoint;
193+
return this;
194+
}
195+
196+
/**
197+
* Optional revocation endpoint.
198+
*
199+
* @param revocationEndpoint the revocation endpoint
200+
* @return the builder
201+
*/
202+
public Builder revocationEndpoint(@NonNull String revocationEndpoint) {
203+
mConfiguration.mRevocationEndpoint = revocationEndpoint;
204+
return this;
205+
}
206+
207+
/**
208+
* Optional end session endpoint.
209+
*
210+
* @param endSessionEndpoint the end session endpoint
211+
* @return the builder
212+
*/
213+
public Builder endSessionEndpoint(@NonNull String endSessionEndpoint) {
214+
mConfiguration.mEndSessionEndpoint = endSessionEndpoint;
215+
return this;
216+
}
217+
218+
/**
219+
* Create the custom configuration.
220+
*
221+
* @return Custom configuration
222+
* @throws IllegalStateException - If missing required endpoints.
223+
*/
224+
public CustomConfiguration create() throws IllegalStateException {
225+
validate();
226+
return mConfiguration;
227+
}
228+
229+
private void validate() {
230+
if (TextUtils.isEmpty(mConfiguration.getAuthorizationEndpoint())) {
231+
throw new IllegalStateException("No authorization endpoint specified");
232+
}
233+
if (TextUtils.isEmpty(mConfiguration.getTokenEndpoint())) {
234+
throw new IllegalStateException("No token endpoint specified");
235+
}
236+
}
237+
}
238+
}

0 commit comments

Comments
 (0)