Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit50e7c96

Browse files
committed
Merge branch 'device-code-flow' ofhttps://github.com/rebarbora-mckvak/scribejava into rebarbora-mckvak-device-code-flow
2 parentsacb0972 +7bb59c3 commit50e7c96

File tree

6 files changed

+172
-8
lines changed

6 files changed

+172
-8
lines changed

‎scribejava-apis/src/main/java/com/github/scribejava/apis/microsoftazureactivedirectory/BaseMicrosoftAzureActiveDirectoryApi.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ protected String getAuthorizationBaseUrl() {
3030
returnMSFT_LOGIN_URL +tenant +OAUTH_2 +getEndpointVersionPath() +"/authorize";
3131
}
3232

33+
@Override
34+
publicStringgetDeviceAuthorizationUrl() {
35+
returnMSFT_LOGIN_URL +tenant +OAUTH_2 +getEndpointVersionPath() +"/devicecode";
36+
}
37+
3338
@Override
3439
publicClientAuthenticationgetClientAuthentication() {
3540
returnRequestBodyAuthenticationScheme.instance();

‎scribejava-core/src/main/java/com/github/scribejava/core/builder/api/DefaultApi20.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,8 @@ public BearerSignature getBearerSignature() {
121121
publicClientAuthenticationgetClientAuthentication() {
122122
returnHttpBasicAuthenticationScheme.instance();
123123
}
124+
125+
publicStringgetDeviceAuthorizationUrl() {
126+
returnnull;
127+
}
124128
}

‎scribejava-core/src/main/java/com/github/scribejava/core/extractors/OAuth2AccessTokenJsonExtractor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ protected OAuth2AccessToken createToken(String accessToken, String tokenType, In
9393
returnnewOAuth2AccessToken(accessToken,tokenType,expiresIn,refreshToken,scope,rawResponse);
9494
}
9595

96-
protectedstaticJsonNodeextractRequiredParameter(JsonNodeerrorNode,StringparameterName,StringrawResponse)
96+
publicstaticJsonNodeextractRequiredParameter(JsonNodeerrorNode,StringparameterName,StringrawResponse)
9797
throwsOAuthException {
9898
finalJsonNodevalue =errorNode.get(parameterName);
9999

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
packagecom.github.scribejava.core.model;
2+
3+
publicclassDeviceCode {
4+
privateStringdeviceCode;
5+
privateStringuserCode;
6+
privateStringverificationUri;
7+
privateintintervalSeconds;
8+
privatelongexpiresAtMillis;
9+
10+
publicDeviceCode(StringdeviceCode,StringuserCode,StringverificationUri,
11+
intintervalSeconds,intexpiresInSeconds) {
12+
this.deviceCode =deviceCode;
13+
this.userCode =userCode;
14+
this.verificationUri =verificationUri;
15+
this.intervalSeconds =intervalSeconds;
16+
expiresAtMillis =System.currentTimeMillis() + (expiresInSeconds *1000);
17+
}
18+
19+
publicStringgetDeviceCode() {
20+
returndeviceCode;
21+
}
22+
23+
publicStringgetUserCode() {
24+
returnuserCode;
25+
}
26+
27+
publicStringgetVerificationUri() {
28+
returnverificationUri;
29+
}
30+
31+
publicintgetIntervalSeconds() {
32+
returnintervalSeconds;
33+
}
34+
35+
publiclonggetExpiresAtMillis() {
36+
returnexpiresAtMillis;
37+
}
38+
}

‎scribejava-core/src/main/java/com/github/scribejava/core/oauth/OAuth20Service.java

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,38 @@
11
packagecom.github.scribejava.core.oauth;
22

3-
importjava.io.IOException;
4-
importjava.io.OutputStream;
5-
importjava.util.concurrent.Future;
3+
importcom.fasterxml.jackson.databind.JsonNode;
4+
importcom.fasterxml.jackson.databind.ObjectMapper;
65
importcom.github.scribejava.core.builder.api.DefaultApi20;
76
importcom.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor;
87
importcom.github.scribejava.core.httpclient.HttpClient;
98
importcom.github.scribejava.core.httpclient.HttpClientConfig;
9+
importcom.github.scribejava.core.model.DeviceCode;
1010
importcom.github.scribejava.core.model.OAuth2AccessToken;
11+
importcom.github.scribejava.core.model.OAuth2AccessTokenErrorResponse;
1112
importcom.github.scribejava.core.model.OAuth2Authorization;
1213
importcom.github.scribejava.core.model.OAuthAsyncRequestCallback;
1314
importcom.github.scribejava.core.model.OAuthConstants;
1415
importcom.github.scribejava.core.model.OAuthRequest;
1516
importcom.github.scribejava.core.model.Response;
1617
importcom.github.scribejava.core.model.Verb;
18+
importcom.github.scribejava.core.oauth2.OAuth2Error;
1719
importcom.github.scribejava.core.pkce.PKCE;
18-
importjava.util.Map;
19-
importjava.util.concurrent.ExecutionException;
2020
importcom.github.scribejava.core.revoke.TokenTypeHint;
21+
importjava.io.IOException;
22+
importjava.io.OutputStream;
2123
importjava.io.UnsupportedEncodingException;
2224
importjava.net.URLDecoder;
25+
importjava.util.Map;
26+
importjava.util.concurrent.ExecutionException;
27+
importjava.util.concurrent.Future;
28+
29+
importstaticcom.github.scribejava.core.extractors.OAuth2AccessTokenJsonExtractor.extractRequiredParameter;
30+
importstaticcom.github.scribejava.core.oauth2.OAuth2Error.AUTHORIZATION_PENDING;
31+
importstaticcom.github.scribejava.core.oauth2.OAuth2Error.SLOW_DOWN;
32+
importstaticjava.lang.Thread.sleep;
2333

2434
publicclassOAuth20ServiceextendsOAuthService {
35+
protectedstaticfinalObjectMapperOBJECT_MAPPER =newObjectMapper();
2536

2637
privatestaticfinalStringVERSION ="2.0";
2738
privatefinalDefaultApi20api;
@@ -493,4 +504,83 @@ public String getResponseType() {
493504
publicStringgetDefaultScope() {
494505
returndefaultScope;
495506
}
507+
508+
/**
509+
* Requests a device code from a server.
510+
*
511+
* @see <a href="https://tools.ietf.org/html/rfc8628#section-3">rfc8628</a>
512+
* @see <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code">
513+
* azure v2-oauth2-device-code</a>
514+
*/
515+
publicDeviceCodegetDeviceCode()throwsInterruptedException,ExecutionException,IOException {
516+
finalOAuthRequestrequest =newOAuthRequest(Verb.POST,api.getDeviceAuthorizationUrl());
517+
request.addBodyParameter(OAuthConstants.CLIENT_ID,getApiKey());
518+
request.addBodyParameter(OAuthConstants.SCOPE,getDefaultScope());
519+
try (Responseresponse =execute(request)) {
520+
finalStringbody =response.getBody();
521+
if (response.getCode() ==200) {
522+
finalJsonNoden =OBJECT_MAPPER.readTree(body);
523+
returnnewDeviceCode(
524+
extractRequiredParameter(n,"device_code",body).textValue(),
525+
extractRequiredParameter(n,"user_code",body).textValue(),
526+
extractRequiredParameter(n,"verification_uri",body).textValue(),
527+
n.path("interval").asInt(5),
528+
extractRequiredParameter(n,"expires_in",body).intValue());
529+
}else {
530+
OAuth2AccessTokenJsonExtractor.instance().generateError(body);
531+
thrownewIllegalStateException();// generateError() always throws an exception
532+
}
533+
}
534+
}
535+
536+
/**
537+
* Attempts to get a token from a server.
538+
* Function {@link #pollDeviceAccessToken(DeviceCode)} is usually used instead of this.
539+
*
540+
* @return token
541+
* @throws OAuth2AccessTokenErrorResponse
542+
* If {@link OAuth2AccessTokenErrorResponse#getError()} is
543+
* {@link OAuth2Error#AUTHORIZATION_PENDING} or {@link OAuth2Error#SLOW_DOWN},
544+
* another attempt should be made after a while.
545+
*
546+
* @see #getDeviceCode()
547+
*/
548+
publicOAuth2AccessTokengetAccessTokenDeviceCodeGrant(DeviceCodedeviceCode)
549+
throwsIOException,InterruptedException,ExecutionException {
550+
finalOAuthRequestrequest =newOAuthRequest(Verb.POST,api.getAccessTokenEndpoint());
551+
request.addParameter(OAuthConstants.GRANT_TYPE,"urn:ietf:params:oauth:grant-type:device_code");
552+
request.addBodyParameter(OAuthConstants.CLIENT_ID,getApiKey());
553+
request.addParameter("device_code",deviceCode.getDeviceCode());
554+
try (Responseresponse =execute(request)) {
555+
returnapi.getAccessTokenExtractor().extract(response);
556+
}
557+
}
558+
559+
/**
560+
* Periodically tries to get a token from a server (waiting for the user to give consent).
561+
*
562+
* @return token
563+
* @throws OAuth2AccessTokenErrorResponse
564+
* Indicates OAuth error.
565+
*
566+
* @see #getDeviceCode()
567+
*/
568+
publicOAuth2AccessTokenpollDeviceAccessToken(DeviceCodedeviceCode)
569+
throwsInterruptedException,ExecutionException,IOException {
570+
longintervalMillis =deviceCode.getIntervalSeconds() *1000;
571+
while (true) {
572+
try {
573+
returngetAccessTokenDeviceCodeGrant(deviceCode);
574+
}catch (OAuth2AccessTokenErrorResponsee) {
575+
if (e.getError() !=AUTHORIZATION_PENDING) {
576+
if (e.getError() ==SLOW_DOWN) {
577+
intervalMillis +=5000;
578+
}else {
579+
throwe;
580+
}
581+
}
582+
}
583+
sleep(intervalMillis);
584+
}
585+
}
496586
}

‎scribejava-core/src/main/java/com/github/scribejava/core/oauth2/OAuth2Error.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
packagecom.github.scribejava.core.oauth2;
22

3+
importjava.util.EnumSet;
4+
importjava.util.Set;
5+
6+
importstaticjava.util.Collections.unmodifiableSet;
7+
38
publicenumOAuth2Error {
49
/**
510
* @see <a href="https://tools.ietf.org/html/rfc6749#section-4.1.2.1">RFC 6749, 4.1.2.1 Error Response</a>
@@ -67,7 +72,29 @@ public enum OAuth2Error {
6772
* @see <a href="https://tools.ietf.org/html/rfc7009#section-4.1">RFC 7009, 4.1. OAuth Extensions Error
6873
* Registration</a>
6974
*/
70-
UNSUPPORTED_TOKEN_TYPE("unsupported_token_type");
75+
UNSUPPORTED_TOKEN_TYPE("unsupported_token_type"),
76+
77+
/**
78+
* @see <a href="https://tools.ietf.org/html/rfc8628#section-3.5">rfc8628#section-3.5</a>
79+
*/
80+
AUTHORIZATION_PENDING("authorization_pending"),
81+
82+
/**
83+
* @see <a href="https://tools.ietf.org/html/rfc8628#section-3.5">rfc8628#section-3.5</a>
84+
*/
85+
SLOW_DOWN("slow_down"),
86+
87+
/**
88+
* @see <a href="https://tools.ietf.org/html/rfc8628#section-3.5">rfc8628#section-3.5</a>
89+
*/
90+
EXPIRED_TOKEN("expired_token"),
91+
;
92+
93+
/**
94+
* Unlike {@link #values()} which creates a new array every time, this always
95+
* returns the same immutable object.
96+
*/
97+
publicstaticfinalSet<OAuth2Error>VALUES =unmodifiableSet(EnumSet.allOf(OAuth2Error.class));
7198

7299
privatefinalStringerrorString;
73100

@@ -76,7 +103,7 @@ public enum OAuth2Error {
76103
}
77104

78105
publicstaticOAuth2ErrorparseFrom(StringerrorString) {
79-
for (OAuth2Errorerror :OAuth2Error.values()) {
106+
for (OAuth2Errorerror :VALUES) {
80107
if (error.errorString.equals(errorString)) {
81108
returnerror;
82109
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp