001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * 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 distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jwt.proc;
019
020
021import java.util.Date;
022
023import com.nimbusds.jose.proc.SecurityContext;
024import com.nimbusds.jwt.JWTClaimsSet;
025import com.nimbusds.jwt.util.DateUtils;
026import net.jcip.annotations.ThreadSafe;
027
028
029/**
030 * Default JWT claims verifier. This class is thread-safe.
031 *
032 * <p>Performs the following checks:
033 *
034 * <ol>
035 *     <li>If an expiration time (exp) claim is present, makes sure it is
036 *         ahead of the current time, else the JWT claims set is rejected.
037 *     <li>If a not-before-time (nbf) claim is present, makes sure it is
038 *         before the current time, else the JWT claims set is rejected.
039 * </ol>
040 *
041 * <p>This class may be extended to perform additional checks.
042 *
043 * @author Vladimir Dzhuvinov
044 * @version 2016-07-25
045 */
046@ThreadSafe
047public class DefaultJWTClaimsVerifier <C extends SecurityContext> implements JWTClaimsSetVerifier<C>, JWTClaimsVerifier, ClockSkewAware {
048
049
050        /**
051         * The default maximum acceptable clock skew, in seconds (60).
052         */
053        public static final int DEFAULT_MAX_CLOCK_SKEW_SECONDS = 60;
054
055
056        // Cache exceptions
057
058
059        /**
060         * Expired JWT.
061         */
062        private static final BadJWTException EXPIRED_JWT_EXCEPTION = new BadJWTException("Expired JWT");
063
064
065        /**
066         * JWT before use time.
067         */
068        private static final BadJWTException JWT_BEFORE_USE_EXCEPTION = new BadJWTException("JWT before use time");
069
070
071        /**
072         * The maximum acceptable clock skew, in seconds.
073         */
074        private int maxClockSkew = DEFAULT_MAX_CLOCK_SKEW_SECONDS;
075
076
077        @Override
078        public int getMaxClockSkew() {
079                return maxClockSkew;
080        }
081
082
083        @Override
084        public void setMaxClockSkew(int maxClockSkewSeconds) {
085                maxClockSkew = maxClockSkewSeconds;
086        }
087
088
089        @Override
090        public void verify(final JWTClaimsSet claimsSet)
091                throws BadJWTException {
092
093                verify(claimsSet, null);
094        }
095        
096        
097        @Override
098        public void verify(final JWTClaimsSet claimsSet, final C context)
099                throws BadJWTException {
100                
101                final Date now = new Date();
102                
103                final Date exp = claimsSet.getExpirationTime();
104                
105                if (exp != null) {
106                        
107                        if (! DateUtils.isAfter(exp, now, maxClockSkew)) {
108                                throw EXPIRED_JWT_EXCEPTION;
109                        }
110                }
111                
112                final Date nbf = claimsSet.getNotBeforeTime();
113                
114                if (nbf != null) {
115                        
116                        if (! DateUtils.isBefore(nbf, now, maxClockSkew)) {
117                                throw JWT_BEFORE_USE_EXCEPTION;
118                        }
119                }
120        }
121}