1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.security.jwt;
23
24 import static com.google.common.base.Preconditions.checkArgument;
25 import static com.google.common.base.Strings.isNullOrEmpty;
26
27 import com.nimbusds.jose.KeySourceException;
28 import com.nimbusds.jose.jwk.JWK;
29 import com.nimbusds.jose.jwk.JWKMatcher;
30 import com.nimbusds.jose.jwk.JWKSelector;
31 import com.nimbusds.jose.jwk.source.JWKSource;
32 import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
33 import com.nimbusds.jose.proc.SecurityContext;
34
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import java.net.MalformedURLException;
39 import java.net.URI;
40 import java.net.URISyntaxException;
41 import java.net.URL;
42 import java.util.Collections;
43 import java.util.List;
44
45
46
47
48 public class JWKSetProvider {
49
50
51 private static final Logger logger = LoggerFactory.getLogger(JWKSetProvider.class);
52
53 private JWKSource<SecurityContext> jwkSource;
54 private JWKSelector selector;
55
56
57
58
59
60
61
62
63 public JWKSetProvider(String jwksUrl, long ttl, long refreshTimeout) {
64 URL url = urlFromString(jwksUrl);
65
66 selector = new JWKSelector(
67 new JWKMatcher.Builder()
68 .build());
69
70 jwkSource = JWKSourceBuilder.create(url)
71 .cache(ttl, refreshTimeout)
72 .retrying(true)
73 .build();
74 }
75
76
77
78
79
80
81
82 private static URL urlFromString(String url) {
83 checkArgument(!isNullOrEmpty(url), "A URL is required");
84 try {
85 final URI uri = new URI(url).normalize();
86 return uri.toURL();
87 } catch (MalformedURLException | URISyntaxException e) {
88 throw new IllegalArgumentException("Invalid JWKS URI", e);
89 }
90 }
91
92
93
94
95
96
97 public List<JWK> getAll() {
98 try {
99 return jwkSource.get(selector, null);
100 } catch (KeySourceException e) {
101 logger.error("Error while loading from JWKS cache: " + e.getMessage());
102 return Collections.emptyList();
103 }
104 }
105 }