View Javadoc
1   package de.dlr.shepard.auth.security;
2   
3   import de.dlr.shepard.common.exceptions.ShepardProcessingException;
4   import io.quarkus.logging.Log;
5   import jakarta.enterprise.context.RequestScoped;
6   import jakarta.ws.rs.ProcessingException;
7   import jakarta.ws.rs.WebApplicationException;
8   import jakarta.ws.rs.client.Client;
9   import jakarta.ws.rs.client.ClientBuilder;
10  import jakarta.ws.rs.core.HttpHeaders;
11  import jakarta.ws.rs.core.MediaType;
12  import java.net.URI;
13  import java.net.URISyntaxException;
14  import org.eclipse.microprofile.config.ConfigProvider;
15  
16  @RequestScoped
17  public final class UserinfoService {
18  
19    private static final String WELL_KNOWN_PATH = ".well-known/openid-configuration";
20  
21    private final URI oidcConfigurationURI;
22    private String userinfoEndpoint;
23  
24    private final Client client = ClientBuilder.newClient();
25  
26    public UserinfoService() {
27      String oidcAuthority = ConfigProvider.getConfig().getValue("oidc.authority", String.class);
28      try {
29        URI base = new URI(oidcAuthority + "/").normalize();
30        oidcConfigurationURI = base.resolve(WELL_KNOWN_PATH);
31      } catch (URISyntaxException e) {
32        throw new ShepardProcessingException(e.getMessage());
33      }
34    }
35  
36    protected void init() {
37      var openIdConfiguration = getOpenIdConfiguration();
38      if (openIdConfiguration == null) {
39        throw new ShepardProcessingException("Could not fetch openid configuration");
40      }
41      userinfoEndpoint = openIdConfiguration.getUserinfoEndpoint();
42    }
43  
44    public Userinfo fetchUserinfo(String accessToken) {
45      if (userinfoEndpoint == null) {
46        init();
47      }
48  
49      var userinfo = getUserinfo(userinfoEndpoint, accessToken);
50      if (userinfo == null) {
51        throw new ShepardProcessingException("Could not fetch userinfo");
52      }
53      return userinfo;
54    }
55  
56    private OpenIdConfiguration getOpenIdConfiguration() {
57      var request = client.target(oidcConfigurationURI).request(MediaType.APPLICATION_JSON).buildGet();
58  
59      OpenIdConfiguration response;
60      try {
61        response = request.invoke(OpenIdConfiguration.class);
62      } catch (ProcessingException | WebApplicationException e) {
63        Log.errorf("Request was unsuccessful: URI: %s, Error: %s", oidcConfigurationURI.toString(), e.getMessage());
64        return null;
65      }
66      return response;
67    }
68  
69    private Userinfo getUserinfo(String uri, String bearer) {
70      var request = client
71        .target(uri)
72        .request(MediaType.APPLICATION_JSON)
73        .header(HttpHeaders.AUTHORIZATION, bearer)
74        .buildGet();
75  
76      Userinfo response;
77      try {
78        response = request.invoke(Userinfo.class);
79      } catch (ProcessingException | WebApplicationException e) {
80        Log.errorf("Request was unsuccessful: URI: %s, Error: %s", uri, e.getMessage());
81        return null;
82      }
83      return response;
84    }
85  }