001/*******************************************************************************
002 * Copyright 2018 The MIT Internet Trust Consortium
003 *
004 * Portions copyright 2011-2013 The MITRE Corporation
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 *******************************************************************************/
018/**
019 *
020 */
021package org.mitre.oauth2.introspectingfilter.service.impl;
022
023import java.text.ParseException;
024
025import org.mitre.oauth2.introspectingfilter.service.IntrospectionConfigurationService;
026import org.mitre.oauth2.model.RegisteredClient;
027import org.mitre.openid.connect.client.service.ClientConfigurationService;
028import org.mitre.openid.connect.client.service.ServerConfigurationService;
029import org.mitre.openid.connect.config.ServerConfiguration;
030
031import com.google.common.base.Strings;
032import com.nimbusds.jwt.JWT;
033import com.nimbusds.jwt.JWTParser;
034
035/**
036 *
037 * Parses the incoming accesstoken as a JWT and determines the issuer based on
038 * the "iss" field inside the JWT. Uses the ServerConfigurationService to determine
039 * the introspection URL for that issuer.
040 *
041 * @author jricher
042 *
043 */
044public class JWTParsingIntrospectionConfigurationService implements IntrospectionConfigurationService {
045
046        private ServerConfigurationService serverConfigurationService;
047        private ClientConfigurationService clientConfigurationService;
048
049        /**
050         * @return the serverConfigurationService
051         */
052        public ServerConfigurationService getServerConfigurationService() {
053                return serverConfigurationService;
054        }
055
056        /**
057         * @param serverConfigurationService the serverConfigurationService to set
058         */
059        public void setServerConfigurationService(ServerConfigurationService serverConfigurationService) {
060                this.serverConfigurationService = serverConfigurationService;
061        }
062
063        /**
064         * @param clientConfigurationService the clientConfigurationService to set
065         */
066        public void setClientConfigurationService(ClientConfigurationService clientConfigurationService) {
067                this.clientConfigurationService = clientConfigurationService;
068        }
069
070        private String getIssuer(String accessToken) {
071                try {
072                        JWT jwt = JWTParser.parse(accessToken);
073
074                        String issuer = jwt.getJWTClaimsSet().getIssuer();
075
076                        return issuer;
077
078                } catch (ParseException e) {
079                        throw new IllegalArgumentException("Unable to parse JWT", e);
080                }
081        }
082
083        /* (non-Javadoc)
084         * @see org.mitre.oauth2.introspectingfilter.IntrospectionConfigurationService#getIntrospectionUrl(java.lang.String)
085         */
086        @Override
087        public String getIntrospectionUrl(String accessToken) {
088                String issuer = getIssuer(accessToken);
089                if (!Strings.isNullOrEmpty(issuer)) {
090                        ServerConfiguration server = serverConfigurationService.getServerConfiguration(issuer);
091                        if (server != null) {
092                                if (!Strings.isNullOrEmpty(server.getIntrospectionEndpointUri())) {
093                                        return server.getIntrospectionEndpointUri();
094                                } else {
095                                        throw new IllegalArgumentException("Server does not have Introspection Endpoint defined");
096                                }
097                        } else {
098                                throw new IllegalArgumentException("Could not find server configuration for issuer " + issuer);
099                        }
100                } else {
101                        throw new IllegalArgumentException("No issuer claim found in JWT");
102                }
103        }
104
105        /* (non-Javadoc)
106         * @see org.mitre.oauth2.introspectingfilter.service.IntrospectionConfigurationService#getClientConfiguration(java.lang.String)
107         */
108        @Override
109        public RegisteredClient getClientConfiguration(String accessToken) {
110
111                String issuer = getIssuer(accessToken);
112                if (!Strings.isNullOrEmpty(issuer)) {
113                        ServerConfiguration server = serverConfigurationService.getServerConfiguration(issuer);
114                        if (server != null) {
115                                RegisteredClient client = clientConfigurationService.getClientConfiguration(server);
116                                if (client != null) {
117                                        return client;
118                                } else {
119                                        throw new IllegalArgumentException("Could not find client configuration for issuer " + issuer);
120                                }
121                        } else {
122                                throw new IllegalArgumentException("Could not find server configuration for issuer " + issuer);
123                        }
124                } else {
125                        throw new IllegalArgumentException("No issuer claim found in JWT");
126                }
127
128        }
129
130
131
132}