001/*******************************************************************************
002 * Copyright 2017 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.openid.connect.client.service.impl;
022
023import java.net.URISyntaxException;
024import java.util.Map;
025import java.util.Map.Entry;
026
027import org.apache.http.client.utils.URIBuilder;
028import org.mitre.jwt.encryption.service.JWTEncryptionAndDecryptionService;
029import org.mitre.jwt.signer.service.impl.JWKSetCacheService;
030import org.mitre.oauth2.model.RegisteredClient;
031import org.mitre.openid.connect.client.service.AuthRequestUrlBuilder;
032import org.mitre.openid.connect.config.ServerConfiguration;
033import org.springframework.security.authentication.AuthenticationServiceException;
034
035import com.google.common.base.Joiner;
036import com.google.common.base.Strings;
037import com.nimbusds.jose.EncryptionMethod;
038import com.nimbusds.jose.JWEAlgorithm;
039import com.nimbusds.jose.JWEHeader;
040import com.nimbusds.jwt.EncryptedJWT;
041import com.nimbusds.jwt.JWTClaimsSet;
042
043/**
044 * @author jricher
045 *
046 */
047public class EncryptedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
048
049        private JWKSetCacheService encrypterService;
050
051        private JWEAlgorithm alg;
052        private EncryptionMethod enc;
053
054
055        /* (non-Javadoc)
056         * @see org.mitre.openid.connect.client.service.AuthRequestUrlBuilder#buildAuthRequestUrl(org.mitre.openid.connect.config.ServerConfiguration, org.mitre.oauth2.model.RegisteredClient, java.lang.String, java.lang.String, java.lang.String, java.util.Map)
057         */
058        @Override
059        public String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map<String, String> options, String loginHint) {
060
061                // create our signed JWT for the request object
062                JWTClaimsSet.Builder claims = new JWTClaimsSet.Builder();
063
064                //set parameters to JwtClaims
065                claims.claim("response_type", "code");
066                claims.claim("client_id", clientConfig.getClientId());
067                claims.claim("scope", Joiner.on(" ").join(clientConfig.getScope()));
068
069                // build our redirect URI
070                claims.claim("redirect_uri", redirectUri);
071
072                // this comes back in the id token
073                claims.claim("nonce", nonce);
074
075                // this comes back in the auth request return
076                claims.claim("state", state);
077
078                // Optional parameters
079                for (Entry<String, String> option : options.entrySet()) {
080                        claims.claim(option.getKey(), option.getValue());
081                }
082
083                // if there's a login hint, send it
084                if (!Strings.isNullOrEmpty(loginHint)) {
085                        claims.claim("login_hint", loginHint);
086                }
087
088                EncryptedJWT jwt = new EncryptedJWT(new JWEHeader(alg, enc), claims.build());
089
090                JWTEncryptionAndDecryptionService encryptor = encrypterService.getEncrypter(serverConfig.getJwksUri());
091
092                encryptor.encryptJwt(jwt);
093
094                try {
095                        URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri());
096                        uriBuilder.addParameter("request", jwt.serialize());
097
098                        // build out the URI
099                        return uriBuilder.build().toString();
100                } catch (URISyntaxException e) {
101                        throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e);
102                }
103        }
104
105        /**
106         * @return the encrypterService
107         */
108        public JWKSetCacheService getEncrypterService() {
109                return encrypterService;
110        }
111
112        /**
113         * @param encrypterService the encrypterService to set
114         */
115        public void setEncrypterService(JWKSetCacheService encrypterService) {
116                this.encrypterService = encrypterService;
117        }
118
119        /**
120         * @return the alg
121         */
122        public JWEAlgorithm getAlg() {
123                return alg;
124        }
125
126        /**
127         * @param alg the alg to set
128         */
129        public void setAlg(JWEAlgorithm alg) {
130                this.alg = alg;
131        }
132
133        /**
134         * @return the enc
135         */
136        public EncryptionMethod getEnc() {
137                return enc;
138        }
139
140        /**
141         * @param enc the enc to set
142         */
143        public void setEnc(EncryptionMethod enc) {
144                this.enc = enc;
145        }
146
147}