5
5
6
6
import com .azure .core .credential .AzureKeyCredential ;
7
7
import com .azure .core .http .HttpHeaderName ;
8
+ import com .azure .core .http .HttpHeaders ;
8
9
import com .azure .core .http .HttpPipelineCallContext ;
9
10
import com .azure .core .http .HttpPipelineNextPolicy ;
10
11
import com .azure .core .http .HttpPipelineNextSyncPolicy ;
11
12
import com .azure .core .http .HttpResponse ;
13
+ import com .azure .core .util .FluxUtil ;
12
14
import com .azure .core .util .logging .ClientLogger ;
13
15
import reactor .core .publisher .Mono ;
14
16
@@ -25,18 +27,7 @@ public final class AzureKeyCredentialPolicy implements HttpPipelinePolicy {
25
27
private static final ClientLogger LOGGER = new ClientLogger (AzureKeyCredentialPolicy .class );
26
28
private final HttpHeaderName name ;
27
29
private final AzureKeyCredential credential ;
28
-
29
- private final HttpPipelineSyncPolicy inner = new HttpPipelineSyncPolicy () {
30
- @ Override
31
- protected void beforeSendingRequest (HttpPipelineCallContext context ) {
32
- if ("http" .equals (context .getHttpRequest ().getUrl ().getProtocol ())) {
33
- throw LOGGER .logExceptionAsError (
34
- new IllegalStateException ("Key credentials require HTTPS to prevent leaking the key." ));
35
- }
36
-
37
- context .getHttpRequest ().setHeader (name , credential .getKey ());
38
- }
39
- };
30
+ private final String prefix ;
40
31
41
32
/**
42
33
* Creates a policy that uses the passed {@link AzureKeyCredential} to set the specified header name.
@@ -47,23 +38,64 @@ protected void beforeSendingRequest(HttpPipelineCallContext context) {
47
38
* @throws IllegalArgumentException If {@code name} is empty.
48
39
*/
49
40
public AzureKeyCredentialPolicy (String name , AzureKeyCredential credential ) {
50
- Objects .requireNonNull (credential , "'credential' cannot be null." );
41
+ this (name , credential , null );
42
+ }
43
+
44
+ /**
45
+ * Creates a policy that uses the passed {@link AzureKeyCredential} to set the specified header name.
46
+ * <p>
47
+ * The {@code prefix} will be applied before the {@link AzureKeyCredential#getKey()} when setting the header. A
48
+ * space will be inserted between {@code prefix} and credential.
49
+ *
50
+ * @param name The name of the key header that will be set to {@link AzureKeyCredential#getKey()}.
51
+ * @param credential The {@link AzureKeyCredential} containing the authorization key to use.
52
+ * @param prefix The prefix to apply before the credential, for example "SharedAccessKey credential".
53
+ * @throws NullPointerException If {@code name} or {@code credential} is {@code null}.
54
+ * @throws IllegalArgumentException If {@code name} is empty.
55
+ */
56
+ public AzureKeyCredentialPolicy (String name , AzureKeyCredential credential , String prefix ) {
57
+ this (validateName (name ), Objects .requireNonNull (credential , "'credential' cannot be null." ), prefix );
58
+ }
59
+
60
+ private static HttpHeaderName validateName (String name ) {
51
61
Objects .requireNonNull (name , "'name' cannot be null." );
52
62
if (name .isEmpty ()) {
53
63
throw LOGGER .logExceptionAsError (new IllegalArgumentException ("'name' cannot be empty." ));
54
64
}
55
65
56
- this .name = HttpHeaderName .fromString (name );
66
+ return HttpHeaderName .fromString (name );
67
+ }
68
+
69
+ AzureKeyCredentialPolicy (HttpHeaderName name , AzureKeyCredential credential , String prefix ) {
70
+ this .name = name ;
57
71
this .credential = credential ;
72
+ this .prefix = prefix != null ? prefix .trim () : null ;
58
73
}
59
74
60
75
@ Override
61
76
public Mono <HttpResponse > process (HttpPipelineCallContext context , HttpPipelineNextPolicy next ) {
62
- return inner .process (context , next );
77
+ if ("http" .equals (context .getHttpRequest ().getUrl ().getProtocol ())) {
78
+ return FluxUtil .monoError (LOGGER ,
79
+ new IllegalStateException ("Key credentials require HTTPS to prevent leaking the key." ));
80
+ }
81
+
82
+ setCredential (context .getHttpRequest ().getHeaders ());
83
+ return next .process ();
63
84
}
64
85
65
86
@ Override
66
87
public HttpResponse processSync (HttpPipelineCallContext context , HttpPipelineNextSyncPolicy next ) {
67
- return inner .processSync (context , next );
88
+ if ("http" .equals (context .getHttpRequest ().getUrl ().getProtocol ())) {
89
+ throw LOGGER .logExceptionAsError (
90
+ new IllegalStateException ("Key credentials require HTTPS to prevent leaking the key." ));
91
+ }
92
+
93
+ setCredential (context .getHttpRequest ().getHeaders ());
94
+ return next .processSync ();
95
+ }
96
+
97
+ void setCredential (HttpHeaders headers ) {
98
+ String credential = this .credential .getKey ();
99
+ headers .set (name , (prefix == null ) ? credential : prefix + " " + credential );
68
100
}
69
101
}
0 commit comments