Skip to content

Commit 1d4bf8b

Browse files
committed
Update AndroidClient
1 parent 363801e commit 1d4bf8b

File tree

5 files changed

+127
-6
lines changed

5 files changed

+127
-6
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package net.servicestack.client;
2+
3+
import java.util.HashMap;
4+
5+
@Route("/access-token")
6+
@DataContract
7+
public class GetAccessToken implements IReturn<GetAccessTokenResponse>, IPost
8+
{
9+
@DataMember(Order=1)
10+
public String refreshToken = null;
11+
12+
@DataMember(Order=2)
13+
public Boolean useTokenCookie = null;
14+
15+
@DataMember(Order=3)
16+
public HashMap<String,String> meta = null;
17+
18+
public String getRefreshToken() { return refreshToken; }
19+
public GetAccessToken setRefreshToken(String value) { this.refreshToken = value; return this; }
20+
public Boolean isUseTokenCookie() { return useTokenCookie; }
21+
public GetAccessToken setUseTokenCookie(Boolean value) { this.useTokenCookie = value; return this; }
22+
public HashMap<String,String> getMeta() { return meta; }
23+
public GetAccessToken setMeta(HashMap<String,String> value) { this.meta = value; return this; }
24+
private static Object responseType = GetAccessTokenResponse.class;
25+
public Object getResponseType() { return responseType; }
26+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.servicestack.client;
2+
3+
import java.util.HashMap;
4+
5+
@DataContract
6+
public class GetAccessTokenResponse
7+
{
8+
@DataMember(Order=1)
9+
public String accessToken = null;
10+
11+
@DataMember(Order=2)
12+
public HashMap<String,String> meta = null;
13+
14+
@DataMember(Order=3)
15+
public ResponseStatus responseStatus = null;
16+
17+
public String getAccessToken() { return accessToken; }
18+
public GetAccessTokenResponse setAccessToken(String value) { this.accessToken = value; return this; }
19+
public HashMap<String,String> getMeta() { return meta; }
20+
public GetAccessTokenResponse setMeta(HashMap<String,String> value) { this.meta = value; return this; }
21+
public ResponseStatus getResponseStatus() { return responseStatus; }
22+
public GetAccessTokenResponse setResponseStatus(ResponseStatus value) { this.responseStatus = value; return this; }
23+
}

src/AndroidClient/android/src/main/java/net/servicestack/client/JsonServiceClient.java

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.net.URLEncoder;
2727
import java.nio.charset.Charset;
2828
import java.util.Date;
29+
import java.util.List;
2930
import java.util.Map;
3031
import java.util.UUID;
3132

@@ -39,6 +40,7 @@ public class JsonServiceClient implements ServiceClient {
3940
String userName;
4041
String password;
4142
String bearerToken;
43+
String refreshToken;
4244

4345
Integer timeoutMs;
4446
public ConnectionFilter RequestFilter;
@@ -179,7 +181,7 @@ public HttpURLConnection createRequest(String requestUrl, String httpMethod, byt
179181
if (bearerToken != null) {
180182
req.setRequestProperty(HttpHeaders.Authorization, "Bearer " + bearerToken);
181183
req.setRequestProperty("X-Auth", "Bearer"); // HttpURLConnection doesn't allow re-reading Authorization Header
182-
} else if (forceAuthentication || alwaysSendBasicAuthHeaders) {
184+
} else if (getTokenCookie() == null && (forceAuthentication || alwaysSendBasicAuthHeaders)) {
183185
req.setRequestProperty(HttpHeaders.Authorization, "Basic " + Utils.toBase64String(userName + ":" + password));
184186
req.setRequestProperty("X-Auth", "Basic"); // HttpURLConnection doesn't allow re-reading Authorization Header
185187
}
@@ -208,12 +210,11 @@ public HttpURLConnection createRequest(String requestUrl, String httpMethod, byt
208210
}
209211
}
210212

211-
private static boolean shouldAuthenticate(HttpURLConnection req, String userName, String password){
213+
private static boolean shouldAuthenticate(HttpURLConnection req, boolean hasAuthInfo){
212214
try {
213215
return req.getResponseCode() == 401
214-
&& req.getRequestProperty("X-Auth") == null //only auth if auth never attempted
215-
&& userName != null
216-
&& password != null;
216+
&& req.getRequestProperty("X-Auth") == null //only auth if auth never attempted
217+
&& hasAuthInfo;
217218
} catch (IOException e) {
218219
return false;
219220
}
@@ -308,6 +309,21 @@ public void setTokenCookie(String value) {
308309
setCookie("ss-tok", value, (long) (365 * 24 * 60 * 60)); //1 year
309310
}
310311

312+
@Override
313+
public void setRefreshToken(String bearerToken) {
314+
this.refreshToken = bearerToken;
315+
}
316+
317+
@Override
318+
public String getRefreshToken() {
319+
return refreshToken;
320+
}
321+
322+
@Override
323+
public void setRefreshTokenCookie(String value) {
324+
setCookie("ss-reftok", value, (long) (365 * 24 * 60 * 60)); //1 year
325+
}
326+
311327
@Override
312328
public void setCredentials(String userName, String password) {
313329
this.userName = userName;
@@ -370,8 +386,26 @@ public <TResponse> TResponse send(String requestUrl, String httpMethod, byte[] r
370386
if (responseCode >= 400){
371387
boolean success = false;
372388

373-
if (shouldAuthenticate(req, userName, password)){
389+
boolean hasRefreshTokenCookie = getRefreshTokenCookie() != null;
390+
boolean hasRefreshToken = refreshToken != null || hasRefreshTokenCookie;
391+
if (shouldAuthenticate(req, (userName !=null && password != null)
392+
|| bearerToken != null
393+
|| hasRefreshToken)) {
374394
req.disconnect();
395+
396+
if (hasRefreshToken) {
397+
GetAccessToken refreshRequest = new GetAccessToken()
398+
.setRefreshToken(refreshToken);
399+
try {
400+
GetAccessTokenResponse response = post(refreshRequest);
401+
if (response.getAccessToken() != null) {
402+
this.setBearerToken(response.getAccessToken());
403+
}
404+
} catch (WebServiceException e) {
405+
throw new RefreshTokenException(e);
406+
}
407+
}
408+
375409
req = createRequest(requestUrl, httpMethod, requestBody, requestType, true);
376410

377411
success = req.getResponseCode() < 400;
@@ -583,6 +617,28 @@ public HttpURLConnection delete(String path) {
583617
return createRequest(resolveUrl(path), HttpMethods.Delete, null, null);
584618
}
585619

620+
public List<HttpCookie> getCookies() {
621+
CookieManager cookieManager = (CookieManager) CookieHandler.getDefault();
622+
return cookieManager.getCookieStore().getCookies();
623+
}
624+
625+
public String getCookieValue(String name) {
626+
CookieManager cookieManager = (CookieManager) CookieHandler.getDefault();
627+
for (HttpCookie cookie : cookieManager.getCookieStore().getCookies()) {
628+
if (cookie.getName().equals(name)) {
629+
return cookie.getValue();
630+
}
631+
}
632+
return null;
633+
}
634+
635+
public String getTokenCookie() {
636+
return getCookieValue("ss-tok");
637+
}
638+
public String getRefreshTokenCookie() {
639+
return getCookieValue("ss-reftok");
640+
}
641+
586642
@Override
587643
public void setCookie(String name, String value) {
588644
setCookie(name, value, null);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package net.servicestack.client;
2+
3+
public class RefreshTokenException extends RuntimeException {
4+
public RefreshTokenException(WebServiceException innerException) {
5+
super(innerException.getMessage(), innerException);
6+
}
7+
}

src/AndroidClient/android/src/main/java/net/servicestack/client/ServiceClient.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@
99

1010
public interface ServiceClient {
1111
boolean getAlwaysSendBasicAuthHeaders();
12+
1213
void setBearerToken(String value);
1314
String getBearerToken();
1415
void setTokenCookie(String value);
16+
17+
void setRefreshToken(String bearerToken);
18+
String getRefreshToken();
19+
void setRefreshTokenCookie(String value);
20+
1521
void setAlwaysSendBasicAuthHeaders(boolean value);
1622
void setCredentials(String userName, String password);
1723

@@ -51,4 +57,7 @@ public interface ServiceClient {
5157
void setCookie(String name, String value);
5258
void setCookie(String name, String value, Long expiresInSecs);
5359
void clearCookies();
60+
String getCookieValue(String name);
61+
String getTokenCookie();
62+
String getRefreshTokenCookie();
5463
}

0 commit comments

Comments
 (0)