55import com .docusign .esign .client .auth .OAuth ;
66import com .docusign .esign .client .auth .OAuth .OAuthToken ;
77import com .docusign .exception .LauncherException ;
8+
89import java .io .IOException ;
910import java .util .ArrayList ;
1011import java .util .Date ;
1112import java .util .List ;
13+
1214import org .slf4j .Logger ;
1315import org .slf4j .LoggerFactory ;
1416import org .springframework .security .oauth2 .client .OAuth2ClientContext ;
1719import org .springframework .security .oauth2 .client .resource .UserRedirectRequiredException ;
1820import org .springframework .security .oauth2 .common .DefaultOAuth2AccessToken ;
1921import org .springframework .security .oauth2 .common .OAuth2AccessToken ;
22+ import org .springframework .web .servlet .view .RedirectView ;
2023
2124public class JWTOAuth2RestTemplate extends OAuth2RestTemplate {
2225
@@ -44,16 +47,20 @@ public OAuth2AccessToken getAccessToken() throws UserRedirectRequiredException {
4447 context .setAccessToken (accessToken );
4548 } catch (Exception e ) {
4649 context .setAccessToken (null );
47- throw e ;
50+ try {
51+ throw e ;
52+ } catch (LauncherException ex ) {
53+ ex .printStackTrace ();
54+ }
4855 }
4956 }
5057 return accessToken ;
5158 }
5259
53- private OAuth2AccessToken accessToken () {
60+ private OAuth2AccessToken accessToken () throws LauncherException {
5461 logger .info ("Fetching an access token via JWT grant..." );
5562 List <String > scopes = new ArrayList <>();
56- // Only signature scope is needed. Impersonation scope is implied.
63+ // Only signature scope is needed. Impersonation scope is implied.
5764 scopes .add (OAuth .Scope_SIGNATURE );
5865 byte [] privateKeyBytes ;
5966 try {
@@ -71,11 +78,32 @@ private OAuth2AccessToken accessToken() {
7178 privateKeyBytes ,
7279 TOKEN_EXPIRATION_IN_SECONDS );
7380 } catch (IOException | ApiException e ) {
81+ // Special handling for consent_required
82+ String message = e .getMessage ();
83+ String consent_url = "" ;
84+ if (message != null && message .contains ("consent_required" )) {
85+ consent_url = String .format ("https://%s/oauth/auth?prompt=login&response_type=code&scope=%s" +
86+ "&client_id=%s" +
87+ "&redirect_uri=%s" ,
88+ resource .getBaseUrl (),
89+ "signature%20impersonation" ,
90+ resource .getClientId (),
91+ "http://localhost:8080/login%26type%3Djwt" );
92+ System .err .println ("\n C O N S E N T R E Q U I R E D" +
93+ "\n Ask the user who will be impersonated to run the following url: " +
94+ "\n " + consent_url +
95+ "\n \n It will ask the user to login and to approve access by your application." +
96+ "\n Alternatively, an Administrator can use Organization Administration to" +
97+ "\n pre-approve one or more users." );
98+ throw new AccessTokenRequiredException (consent_url , resource );
99+ }
100+
74101 throw new AccessTokenRequiredException (e .getMessage (), resource );
102+
75103 }
76104 apiClient .setAccessToken (oAuthToken .getAccessToken (), oAuthToken .getExpiresIn ());
77105 logger .info ("Done. Continuing..." );
78- return convert (oAuthToken );
106+ return convert (oAuthToken );
79107 }
80108
81109 private static OAuth2AccessToken convert (OAuthToken oAuthToken ) {
0 commit comments