001/*******************************************************************************
002 * Copyright 2018 The MIT Internet Trust Consortium
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *******************************************************************************/
016
017package org.mitre.jwt.assertion.impl;
018
019import java.text.ParseException;
020import java.util.HashMap;
021import java.util.Map;
022
023import org.mitre.jwt.assertion.AssertionValidator;
024import org.mitre.jwt.signer.service.JWTSigningAndValidationService;
025import org.mitre.jwt.signer.service.impl.JWKSetCacheService;
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028import org.springframework.beans.factory.annotation.Autowired;
029
030import com.google.common.base.Strings;
031import com.nimbusds.jwt.JWT;
032import com.nimbusds.jwt.JWTClaimsSet;
033import com.nimbusds.jwt.SignedJWT;
034
035/**
036 * Checks to see if the assertion was signed by a particular authority available from a whitelist
037 * @author jricher
038 *
039 */
040public class WhitelistedIssuerAssertionValidator implements AssertionValidator {
041
042        private static Logger logger = LoggerFactory.getLogger(WhitelistedIssuerAssertionValidator.class);
043
044        /**
045         * Map of issuer -> JWKSetUri
046         */
047        private Map<String, String> whitelist = new HashMap<>();
048
049        /**
050         * @return the whitelist
051         */
052        public Map<String, String> getWhitelist() {
053                return whitelist;
054        }
055
056        /**
057         * @param whitelist the whitelist to set
058         */
059        public void setWhitelist(Map<String, String> whitelist) {
060                this.whitelist = whitelist;
061        }
062
063        @Autowired
064        private JWKSetCacheService jwkCache;
065
066        @Override
067        public boolean isValid(JWT assertion) {
068
069                if (!(assertion instanceof SignedJWT)) {
070                        // unsigned assertion
071                        return false;
072                }
073
074                JWTClaimsSet claims;
075                try {
076                        claims = assertion.getJWTClaimsSet();
077                } catch (ParseException e) {
078                        logger.debug("Invalid assertion claims");
079                        return false;
080                }
081
082                if (Strings.isNullOrEmpty(claims.getIssuer())) {
083                        logger.debug("No issuer for assertion, rejecting");
084                        return false;
085                }
086
087                if (!whitelist.containsKey(claims.getIssuer())) {
088                        logger.debug("Issuer is not in whitelist, rejecting");
089                        return false;
090                }
091
092                String jwksUri = whitelist.get(claims.getIssuer());
093
094                JWTSigningAndValidationService validator = jwkCache.getValidator(jwksUri);
095
096                if (validator.validateSignature((SignedJWT) assertion)) {
097                        return true;
098                } else {
099                        return false;
100                }
101
102        }
103
104}