1616package com .rabbitmq .client .impl ;
1717
1818import com .fasterxml .jackson .databind .ObjectMapper ;
19- import org .slf4j .Logger ;
20- import org .slf4j .LoggerFactory ;
2119
20+ import javax .net .ssl .HostnameVerifier ;
21+ import javax .net .ssl .HttpsURLConnection ;
22+ import javax .net .ssl .SSLSocketFactory ;
2223import java .io .*;
2324import java .net .HttpURLConnection ;
2425import java .net .URL ;
2526import java .net .URLEncoder ;
2627import java .nio .charset .StandardCharsets ;
2728import java .util .*;
28- import java .util .concurrent .CountDownLatch ;
29- import java .util .concurrent .atomic .AtomicBoolean ;
30- import java .util .concurrent .atomic .AtomicReference ;
31- import java .util .concurrent .locks .Lock ;
32- import java .util .concurrent .locks .ReentrantLock ;
3329
34-
35- public class OAuth2ClientCredentialsGrantCredentialsProvider implements CredentialsProvider {
36-
37- private static final Logger LOGGER = LoggerFactory .getLogger (OAuth2ClientCredentialsGrantCredentialsProvider .class );
30+ /**
31+ *
32+ * @see RefreshProtectedCredentialsProvider
33+ */
34+ public class OAuth2ClientCredentialsGrantCredentialsProvider extends RefreshProtectedCredentialsProvider <OAuth2ClientCredentialsGrantCredentialsProvider .Token > {
3835
3936 private static final String UTF_8_CHARSET = "UTF-8" ;
40- private final String serverUri ; // should be renamed to tokenEndpointUri?
37+ private final String tokenEndpointUri ;
4138 private final String clientId ;
4239 private final String clientSecret ;
4340 private final String grantType ;
44- // UAA specific, to distinguish between different users
45- private final String username , password ;
41+
42+ private final Map < String , String > parameters ;
4643
4744 private final ObjectMapper objectMapper = new ObjectMapper ();
4845
4946 private final String id ;
5047
51- private final AtomicReference <Token > token = new AtomicReference <>();
48+ private final HostnameVerifier hostnameVerifier ;
49+ private final SSLSocketFactory sslSocketFactory ;
50+
51+ public OAuth2ClientCredentialsGrantCredentialsProvider (String tokenEndpointUri , String clientId , String clientSecret , String grantType ) {
52+ this (tokenEndpointUri , clientId , clientSecret , grantType , new HashMap <>());
53+ }
54+
55+ public OAuth2ClientCredentialsGrantCredentialsProvider (String tokenEndpointUri , String clientId , String clientSecret , String grantType ,
56+ HostnameVerifier hostnameVerifier , SSLSocketFactory sslSocketFactory ) {
57+ this (tokenEndpointUri , clientId , clientSecret , grantType , new HashMap <>(), hostnameVerifier , sslSocketFactory );
58+ }
5259
53- private final Lock refreshLock = new ReentrantLock ();
54- private final AtomicReference < CountDownLatch > latch = new AtomicReference <>( );
55- private AtomicBoolean refreshInProcess = new AtomicBoolean ( false );
60+ public OAuth2ClientCredentialsGrantCredentialsProvider ( String tokenEndpointUri , String clientId , String clientSecret , String grantType , Map < String , String > parameters ) {
61+ this ( tokenEndpointUri , clientId , clientSecret , grantType , parameters , null , null );
62+ }
5663
57- public OAuth2ClientCredentialsGrantCredentialsProvider (String serverUri , String clientId , String clientSecret , String grantType , String username , String password ) {
58- this .serverUri = serverUri ;
64+ public OAuth2ClientCredentialsGrantCredentialsProvider (String tokenEndpointUri , String clientId , String clientSecret , String grantType , Map <String , String > parameters ,
65+ HostnameVerifier hostnameVerifier , SSLSocketFactory sslSocketFactory ) {
66+ this .tokenEndpointUri = tokenEndpointUri ;
5967 this .clientId = clientId ;
6068 this .clientSecret = clientSecret ;
6169 this .grantType = grantType ;
62- this .username = username ;
63- this .password = password ;
70+ this .parameters = Collections .unmodifiableMap (new HashMap <>(parameters ));
71+ this .hostnameVerifier = hostnameVerifier ;
72+ this .sslSocketFactory = sslSocketFactory ;
6473 this .id = UUID .randomUUID ().toString ();
6574 }
6675
@@ -90,19 +99,8 @@ public String getUsername() {
9099 }
91100
92101 @ Override
93- public String getPassword () {
94- if (token .get () == null ) {
95- refresh ();
96- }
97- return token .get ().getAccess ();
98- }
99-
100- @ Override
101- public Date getExpiration () {
102- if (token .get () == null ) {
103- refresh ();
104- }
105- return token .get ().getExpiration ();
102+ protected String usernameFromToken (Token token ) {
103+ return "" ;
106104 }
107105
108106 protected Token parseToken (String response ) {
@@ -118,47 +116,21 @@ protected Token parseToken(String response) {
118116 }
119117
120118 @ Override
121- public void refresh () {
122- // refresh should happen at once. Other calls wait for the refresh to finish and move on.
123- if (refreshLock .tryLock ()) {
124- LOGGER .debug ("Refreshing token" );
125- try {
126- latch .set (new CountDownLatch (1 ));
127- refreshInProcess .set (true );
128- token .set (retrieveToken ());
129- LOGGER .debug ("Token refreshed" );
130- } finally {
131- latch .get ().countDown ();
132- refreshInProcess .set (false );
133- refreshLock .unlock ();
134- }
135- } else {
136- try {
137- LOGGER .debug ("Waiting for token refresh to be finished" );
138- while (!refreshInProcess .get ()) {
139- Thread .sleep (10 );
140- }
141- latch .get ().await ();
142- LOGGER .debug ("Done waiting for token refresh" );
143- } catch (InterruptedException e ) {
144- Thread .currentThread ().interrupt ();
145- }
146- }
147- }
148-
149119 protected Token retrieveToken () {
150- // FIXME handle TLS specific settings
151120 try {
152121 StringBuilder urlParameters = new StringBuilder ();
153122 encode (urlParameters , "grant_type" , grantType );
154- encode (urlParameters , "username" , username );
155- encode (urlParameters , "password" , password );
123+ for (Map .Entry <String , String > parameter : parameters .entrySet ()) {
124+ encode (urlParameters , parameter .getKey (), parameter .getValue ());
125+ }
156126 byte [] postData = urlParameters .toString ().getBytes (StandardCharsets .UTF_8 );
157127 int postDataLength = postData .length ;
158- URL url = new URL (serverUri );
128+ URL url = new URL (tokenEndpointUri );
129+
159130 // FIXME close connection?
160131 // FIXME set timeout on request
161132 HttpURLConnection conn = (HttpURLConnection ) url .openConnection ();
133+
162134 conn .setDoOutput (true );
163135 conn .setInstanceFollowRedirects (false );
164136 conn .setRequestMethod ("POST" );
@@ -168,6 +140,9 @@ protected Token retrieveToken() {
168140 conn .setRequestProperty ("accept" , "application/json" );
169141 conn .setRequestProperty ("content-length" , Integer .toString (postDataLength ));
170142 conn .setUseCaches (false );
143+
144+ configureHttpConnection (conn );
145+
171146 try (DataOutputStream wr = new DataOutputStream (conn .getOutputStream ())) {
172147 wr .write (postData );
173148 }
@@ -196,6 +171,28 @@ protected Token retrieveToken() {
196171 }
197172 }
198173
174+ @ Override
175+ protected String passwordFromToken (Token token ) {
176+ return token .getAccess ();
177+ }
178+
179+ @ Override
180+ protected Date expirationFromToken (Token token ) {
181+ return token .getExpiration ();
182+ }
183+
184+ protected void configureHttpConnection (HttpURLConnection connection ) {
185+ if (connection instanceof HttpsURLConnection ) {
186+ HttpsURLConnection securedConnection = (HttpsURLConnection ) connection ;
187+ if (this .hostnameVerifier != null ) {
188+ securedConnection .setHostnameVerifier (this .hostnameVerifier );
189+ }
190+ if (this .sslSocketFactory != null ) {
191+ securedConnection .setSSLSocketFactory (this .sslSocketFactory );
192+ }
193+ }
194+ }
195+
199196 @ Override
200197 public boolean equals (Object o ) {
201198 if (this == o ) return true ;
@@ -230,4 +227,59 @@ public String getAccess() {
230227 return access ;
231228 }
232229 }
230+
231+ public static class OAuth2ClientCredentialsGrantCredentialsProviderBuilder {
232+
233+ private final Map <String , String > parameters = new HashMap <>();
234+ private String tokenEndpointUri ;
235+ private String clientId ;
236+ private String clientSecret ;
237+ private String grantType = "client_credentials" ;
238+ private HostnameVerifier hostnameVerifier ;
239+
240+ private SSLSocketFactory sslSocketFactory ;
241+
242+ public OAuth2ClientCredentialsGrantCredentialsProviderBuilder tokenEndpointUri (String tokenEndpointUri ) {
243+ this .tokenEndpointUri = tokenEndpointUri ;
244+ return this ;
245+ }
246+
247+ public OAuth2ClientCredentialsGrantCredentialsProviderBuilder clientId (String clientId ) {
248+ this .clientId = clientId ;
249+ return this ;
250+ }
251+
252+ public OAuth2ClientCredentialsGrantCredentialsProviderBuilder clientSecret (String clientSecret ) {
253+ this .clientSecret = clientSecret ;
254+ return this ;
255+ }
256+
257+ public OAuth2ClientCredentialsGrantCredentialsProviderBuilder grantType (String grantType ) {
258+ this .grantType = grantType ;
259+ return this ;
260+ }
261+
262+ public OAuth2ClientCredentialsGrantCredentialsProviderBuilder parameter (String name , String value ) {
263+ this .parameters .put (name , value );
264+ return this ;
265+ }
266+
267+ public OAuth2ClientCredentialsGrantCredentialsProviderBuilder setHostnameVerifier (HostnameVerifier hostnameVerifier ) {
268+ this .hostnameVerifier = hostnameVerifier ;
269+ return this ;
270+ }
271+
272+ public OAuth2ClientCredentialsGrantCredentialsProviderBuilder setSslSocketFactory (SSLSocketFactory sslSocketFactory ) {
273+ this .sslSocketFactory = sslSocketFactory ;
274+ return this ;
275+ }
276+
277+ public OAuth2ClientCredentialsGrantCredentialsProvider build () {
278+ return new OAuth2ClientCredentialsGrantCredentialsProvider (
279+ tokenEndpointUri , clientId , clientSecret , grantType , parameters ,
280+ hostnameVerifier , sslSocketFactory
281+ );
282+ }
283+
284+ }
233285}
0 commit comments