001/*******************************************************************************
002 * Copyright 2017 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.openid.connect.model;
018
019import java.io.IOException;
020import java.io.ObjectInputStream;
021import java.io.ObjectOutputStream;
022import java.text.ParseException;
023import java.util.ArrayList;
024
025import org.mitre.openid.connect.config.ServerConfiguration;
026import org.springframework.security.authentication.AbstractAuthenticationToken;
027import org.springframework.security.core.GrantedAuthority;
028
029import com.google.common.collect.ImmutableMap;
030import com.nimbusds.jwt.JWT;
031import com.nimbusds.jwt.JWTParser;
032
033/**
034 * AuthenticationToken for use as a data shuttle from the filter to the auth provider.
035 *
036 * @author jricher
037 *
038 */
039public class PendingOIDCAuthenticationToken extends AbstractAuthenticationToken {
040
041        private static final long serialVersionUID = 22100073066377804L;
042
043        private final ImmutableMap<String, String> principal;
044        private final String accessTokenValue; // string representation of the access token
045        private final String refreshTokenValue; // string representation of the refresh token
046        private transient JWT idToken; // this needs a custom serializer
047        private final String issuer; // issuer URL (parsed from the id token)
048        private final String sub; // user id (parsed from the id token)
049
050        private final transient ServerConfiguration serverConfiguration; // server configuration used to fulfill this token, don't serialize it
051
052        /**
053         * Constructs OIDCAuthenticationToken for use as a data shuttle from the filter to the auth provider.
054         *
055         * Set to not-authenticated.
056         *
057         * Constructs a Principal out of the subject and issuer.
058         * @param sub
059         * @param idToken
060         */
061        public PendingOIDCAuthenticationToken (String subject, String issuer,
062                        ServerConfiguration serverConfiguration,
063                        JWT idToken, String accessTokenValue, String refreshTokenValue) {
064
065                super(new ArrayList<GrantedAuthority>(0));
066
067                this.principal = ImmutableMap.of("sub", subject, "iss", issuer);
068                this.sub = subject;
069                this.issuer = issuer;
070                this.idToken = idToken;
071                this.accessTokenValue = accessTokenValue;
072                this.refreshTokenValue = refreshTokenValue;
073
074                this.serverConfiguration = serverConfiguration;
075
076
077                setAuthenticated(false);
078        }
079
080        /*
081         * (non-Javadoc)
082         *
083         * @see org.springframework.security.core.Authentication#getCredentials()
084         */
085        @Override
086        public Object getCredentials() {
087                return accessTokenValue;
088        }
089
090        /**
091         * Get the principal of this object, an immutable map of the subject and issuer.
092         */
093        @Override
094        public Object getPrincipal() {
095                return principal;
096        }
097
098        public String getSub() {
099                return sub;
100        }
101
102        /**
103         * @return the idTokenValue
104         */
105        public JWT getIdToken() {
106                return idToken;
107        }
108
109        /**
110         * @return the accessTokenValue
111         */
112        public String getAccessTokenValue() {
113                return accessTokenValue;
114        }
115
116        /**
117         * @return the refreshTokenValue
118         */
119        public String getRefreshTokenValue() {
120                return refreshTokenValue;
121        }
122
123        /**
124         * @return the serverConfiguration
125         */
126        public ServerConfiguration getServerConfiguration() {
127                return serverConfiguration;
128        }
129
130        /**
131         * @return the issuer
132         */
133        public String getIssuer() {
134                return issuer;
135        }
136
137        /*
138         * Custom serialization to handle the JSON object
139         */
140        private void writeObject(ObjectOutputStream out) throws IOException {
141                out.defaultWriteObject();
142                if (idToken == null) {
143                        out.writeObject(null);
144                } else {
145                        out.writeObject(idToken.serialize());
146                }
147        }
148        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException, ParseException {
149                in.defaultReadObject();
150                Object o = in.readObject();
151                if (o != null) {
152                        idToken = JWTParser.parse((String)o);
153                }
154        }
155
156}