0
# SSL Configuration
1
2
Comprehensive SSL and TLS configuration system for secure HTTPS connections with custom certificates, protocols, and security settings. Play WS provides extensive SSL configuration options for production security requirements.
3
4
## Capabilities
5
6
### SSL Configuration
7
8
Main SSL configuration class for customizing TLS settings.
9
10
```scala { .api }
11
/**
12
* SSL configuration for WS client
13
*/
14
case class SSLConfig(
15
default: Boolean = false,
16
protocol: String = "TLSv1.2",
17
checkRevocation: Option[Boolean] = None,
18
revocationLists: Option[Seq[URL]] = None,
19
enabledCipherSuites: Option[Seq[String]] = None,
20
enabledProtocols: Option[Seq[String]] = Some(Seq("TLSv1.2", "TLSv1.1", "TLSv1")),
21
disabledSignatureAlgorithms: Seq[String] = Seq("MD2", "MD4", "MD5"),
22
disabledKeyAlgorithms: Seq[String] = Seq("RSA keySize < 2048", "DSA keySize < 2048", "EC keySize < 224"),
23
keyManagerConfig: KeyManagerConfig = KeyManagerConfig(),
24
trustManagerConfig: TrustManagerConfig = TrustManagerConfig(),
25
hostnameVerifierClass: Class[_ <: HostnameVerifier] = classOf[DefaultHostnameVerifier],
26
secureRandom: Option[SecureRandom] = None,
27
debug: SSLDebugConfig = SSLDebugConfig(),
28
loose: SSLLooseConfig = SSLLooseConfig()
29
)
30
```
31
32
**Basic SSL Configuration:**
33
34
```scala
35
import play.api.libs.ws.ssl._
36
import java.net.URL
37
38
// Default secure configuration
39
val sslConfig = SSLConfig()
40
41
// Custom protocol and cipher configuration
42
val customSslConfig = SSLConfig(
43
protocol = "TLSv1.2",
44
enabledProtocols = Some(Seq("TLSv1.2")),
45
enabledCipherSuites = Some(Seq(
46
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
47
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
48
))
49
)
50
51
// Apply to WS client configuration
52
val wsConfig = WSClientConfig(ssl = customSslConfig)
53
```
54
55
### Key Store Configuration
56
57
Configuration for client certificates and private keys.
58
59
```scala { .api }
60
/**
61
* Key store configuration for client certificates
62
*/
63
case class KeyStoreConfig(
64
storeType: String = KeyStore.getDefaultType,
65
filePath: Option[String] = None,
66
data: Option[String] = None,
67
password: Option[String] = None
68
)
69
70
/**
71
* Key manager configuration
72
*/
73
case class KeyManagerConfig(
74
algorithm: String = KeyManagerFactory.getDefaultAlgorithm,
75
keyStoreConfigs: Seq[KeyStoreConfig] = Nil
76
)
77
```
78
79
**Client Certificate Configuration:**
80
81
```scala
82
// Configure client certificate from file
83
val keyStoreConfig = KeyStoreConfig(
84
storeType = "PKCS12",
85
filePath = Some("/path/to/client-cert.p12"),
86
password = Some("keystore-password")
87
)
88
89
val keyManagerConfig = KeyManagerConfig(
90
keyStoreConfigs = Seq(keyStoreConfig)
91
)
92
93
val sslConfig = SSLConfig(
94
keyManagerConfig = keyManagerConfig
95
)
96
```
97
98
### Trust Store Configuration
99
100
Configuration for trusted certificate authorities.
101
102
```scala { .api }
103
/**
104
* Trust store configuration for CA certificates
105
*/
106
case class TrustStoreConfig(
107
storeType: String = KeyStore.getDefaultType,
108
filePath: Option[String],
109
data: Option[String]
110
)
111
112
/**
113
* Trust manager configuration
114
*/
115
case class TrustManagerConfig(
116
algorithm: String = TrustManagerFactory.getDefaultAlgorithm,
117
trustStoreConfigs: Seq[TrustStoreConfig] = Nil
118
)
119
```
120
121
**Custom Trust Store Configuration:**
122
123
```scala
124
// Configure custom CA certificates
125
val trustStoreConfig = TrustStoreConfig(
126
storeType = "JKS",
127
filePath = Some("/path/to/truststore.jks")
128
)
129
130
val trustManagerConfig = TrustManagerConfig(
131
trustStoreConfigs = Seq(trustStoreConfig)
132
)
133
134
val sslConfig = SSLConfig(
135
trustManagerConfig = trustManagerConfig
136
)
137
```
138
139
### SSL Debug Configuration
140
141
Comprehensive debugging options for SSL/TLS troubleshooting.
142
143
```scala { .api }
144
/**
145
* SSL debug configuration
146
*/
147
case class SSLDebugConfig(
148
all: Boolean = false,
149
ssl: Boolean = false,
150
certpath: Boolean = false,
151
ocsp: Boolean = false,
152
record: Option[SSLDebugRecordOptions] = None,
153
handshake: Option[SSLDebugHandshakeOptions] = None,
154
keygen: Boolean = false,
155
session: Boolean = false,
156
defaultctx: Boolean = false,
157
sslctx: Boolean = false,
158
sessioncache: Boolean = false,
159
keymanager: Boolean = false,
160
trustmanager: Boolean = false,
161
pluggability: Boolean = false
162
) {
163
/** Check if any debug options are enabled */
164
def enabled: Boolean
165
166
/** Enable all debug options */
167
def withAll: SSLDebugConfig
168
169
/** Enable certificate path debugging */
170
def withCertPath: SSLDebugConfig
171
172
/** Enable OCSP debugging */
173
def withOcsp: SSLDebugConfig
174
}
175
176
/**
177
* SSL debug record options
178
*/
179
case class SSLDebugRecordOptions(
180
plaintext: Boolean = false,
181
packet: Boolean = false
182
)
183
184
/**
185
* SSL debug handshake options
186
*/
187
case class SSLDebugHandshakeOptions(
188
data: Boolean = false,
189
verbose: Boolean = false
190
)
191
```
192
193
**SSL Debug Configuration:**
194
195
```scala
196
// Enable comprehensive SSL debugging
197
val debugConfig = SSLDebugConfig(
198
all = true
199
)
200
201
// Enable specific debug categories
202
val specificDebugConfig = SSLDebugConfig(
203
certpath = true,
204
handshake = Some(SSLDebugHandshakeOptions(verbose = true)),
205
record = Some(SSLDebugRecordOptions(plaintext = true))
206
)
207
208
val sslConfig = SSLConfig(
209
debug = debugConfig
210
)
211
```
212
213
### Loose SSL Configuration
214
215
Configuration for relaxing SSL security (development/testing only).
216
217
```scala { .api }
218
/**
219
* Loose SSL configuration (WARNING: Use only for development/testing)
220
*/
221
case class SSLLooseConfig(
222
allowWeakCiphers: Boolean = false,
223
allowWeakProtocols: Boolean = false,
224
allowLegacyHelloMessages: Option[Boolean] = None,
225
allowUnsafeRenegotiation: Option[Boolean] = None,
226
disableHostnameVerification: Boolean = false,
227
acceptAnyCertificate: Boolean = false
228
)
229
```
230
231
**Development SSL Configuration:**
232
233
```scala
234
// WARNING: Only for development/testing
235
val looseSslConfig = SSLLooseConfig(
236
disableHostnameVerification = true,
237
acceptAnyCertificate = true
238
)
239
240
val developmentSslConfig = SSLConfig(
241
loose = looseSslConfig
242
)
243
```
244
245
### SSL Context Building
246
247
Build custom SSL contexts from configuration.
248
249
```scala { .api }
250
/**
251
* SSL context builder interface
252
*/
253
trait SSLContextBuilder {
254
def build(): SSLContext
255
}
256
257
/**
258
* Simple SSL context builder
259
*/
260
class SimpleSSLContextBuilder(
261
protocol: String,
262
keyManagers: Seq[KeyManager],
263
trustManagers: Seq[TrustManager],
264
secureRandom: Option[SecureRandom]
265
) extends SSLContextBuilder
266
267
/**
268
* Configuration-based SSL context builder
269
*/
270
class ConfigSSLContextBuilder(config: SSLConfig) extends SSLContextBuilder
271
```
272
273
### Protocol and Cipher Utilities
274
275
Utilities for working with SSL protocols and cipher suites.
276
277
```scala { .api }
278
/**
279
* SSL/TLS protocol utilities
280
*/
281
object Protocols {
282
/** Deprecated/insecure protocols to avoid */
283
val deprecatedProtocols: Set[String]
284
285
/** Recommended protocols for current Java version */
286
val recommendedProtocols: Array[String]
287
288
/** Default recommended protocol */
289
val recommendedProtocol: String
290
}
291
292
/**
293
* SSL cipher suite utilities
294
*/
295
object Ciphers {
296
/** Recommended cipher suites */
297
val recommendedCiphers: Seq[String]
298
299
/** Deprecated/weak cipher suites to avoid */
300
val deprecatedCiphers: Set[String]
301
}
302
```
303
304
**Protocol and Cipher Selection:**
305
306
```scala
307
import play.api.libs.ws.ssl.{Protocols, Ciphers}
308
309
// Use recommended protocols and ciphers
310
val secureConfig = SSLConfig(
311
protocol = Protocols.recommendedProtocol,
312
enabledProtocols = Some(Protocols.recommendedProtocols.toSeq),
313
enabledCipherSuites = Some(Ciphers.recommendedCiphers)
314
)
315
```
316
317
### Key Store Builders
318
319
Build key stores from various sources.
320
321
```scala { .api }
322
/**
323
* Key store builder interface
324
*/
325
trait KeyStoreBuilder {
326
def build(): KeyStore
327
}
328
329
/**
330
* String-based key store builder (PEM format)
331
*/
332
class StringBasedKeyStoreBuilder(data: String) extends KeyStoreBuilder
333
334
/**
335
* File-based key store builder
336
*/
337
class FileBasedKeyStoreBuilder(
338
keyStoreType: String,
339
filePath: String,
340
password: Option[Array[Char]]
341
) extends KeyStoreBuilder
342
```
343
344
### System Configuration
345
346
Configure JVM system properties for SSL.
347
348
```scala { .api }
349
/**
350
* System-level SSL configuration
351
*/
352
class SystemConfiguration {
353
/** Configure SSL system properties */
354
def configure(config: WSClientConfig): Unit
355
356
/** Configure unsafe renegotiation */
357
def configureUnsafeRenegotiation(allowUnsafeRenegotiation: Boolean): Unit
358
359
/** Configure legacy hello messages */
360
def configureAllowLegacyHelloMessages(allowLegacyHelloMessages: Boolean): Unit
361
362
/** Configure certificate revocation checking */
363
def configureCheckRevocation(checkRevocation: Boolean): Unit
364
}
365
```
366
367
### Complete SSL Configuration Examples
368
369
**Production HTTPS Configuration:**
370
371
```scala
372
import play.api.libs.ws.ssl._
373
import java.security.SecureRandom
374
375
val productionSslConfig = SSLConfig(
376
protocol = "TLSv1.2",
377
enabledProtocols = Some(Seq("TLSv1.2")),
378
enabledCipherSuites = Some(Seq(
379
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
380
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
381
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
382
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
383
)),
384
checkRevocation = Some(true),
385
secureRandom = Some(new SecureRandom())
386
)
387
388
val wsConfig = WSClientConfig(ssl = productionSslConfig)
389
val client = NingWSClient(NingWSClientConfig(wsClientConfig = wsConfig))
390
```
391
392
**Mutual TLS (mTLS) Configuration:**
393
394
```scala
395
// Client certificate configuration
396
val clientKeyStore = KeyStoreConfig(
397
storeType = "PKCS12",
398
filePath = Some("/etc/ssl/client.p12"),
399
password = Some("client-cert-password")
400
)
401
402
// Custom CA trust store
403
val trustStore = TrustStoreConfig(
404
storeType = "JKS",
405
filePath = Some("/etc/ssl/ca-trust.jks")
406
)
407
408
val mtlsConfig = SSLConfig(
409
keyManagerConfig = KeyManagerConfig(
410
keyStoreConfigs = Seq(clientKeyStore)
411
),
412
trustManagerConfig = TrustManagerConfig(
413
trustStoreConfigs = Seq(trustStore)
414
)
415
)
416
417
val mtlsWsConfig = WSClientConfig(ssl = mtlsConfig)
418
```
419
420
**Self-Signed Certificate Configuration:**
421
422
```scala
423
// Custom trust store with self-signed certificate
424
val selfSignedTrustStore = TrustStoreConfig(
425
storeType = "JKS",
426
filePath = Some("/path/to/self-signed-truststore.jks")
427
)
428
429
val selfSignedConfig = SSLConfig(
430
trustManagerConfig = TrustManagerConfig(
431
trustStoreConfigs = Seq(selfSignedTrustStore)
432
),
433
// Optional: disable hostname verification for self-signed certs
434
loose = SSLLooseConfig(
435
disableHostnameVerification = true
436
)
437
)
438
```
439
440
**SSL Configuration with Custom Hostname Verifier:**
441
442
```scala
443
import javax.net.ssl.HostnameVerifier
444
445
class CustomHostnameVerifier extends HostnameVerifier {
446
override def verify(hostname: String, session: SSLSession): Boolean = {
447
// Custom hostname verification logic
448
hostname.endsWith(".trusted-domain.com")
449
}
450
}
451
452
val customVerifierConfig = SSLConfig(
453
hostnameVerifierClass = classOf[CustomHostnameVerifier]
454
)
455
```
456
457
**Debugging SSL Connection Issues:**
458
459
```scala
460
// Enable comprehensive SSL debugging
461
val debugSslConfig = SSLConfig(
462
debug = SSLDebugConfig(
463
ssl = true,
464
handshake = Some(SSLDebugHandshakeOptions(verbose = true, data = true)),
465
record = Some(SSLDebugRecordOptions(plaintext = true)),
466
certpath = true,
467
trustmanager = true
468
)
469
)
470
471
// This will output detailed SSL information to console
472
val debugWsConfig = WSClientConfig(ssl = debugSslConfig)
473
```