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 *******************************************************************************/
018package org.mitre.openid.connect.model;
019
020import java.io.IOException;
021import java.io.ObjectInputStream;
022import java.io.ObjectOutputStream;
023import java.text.ParseException;
024import java.util.Collection;
025
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 *
035 * @author Michael Walsh, Justin Richer
036 *
037 */
038public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
039
040        private static final long serialVersionUID = 22100073066377804L;
041
042        private final ImmutableMap<String, String> principal;
043        private final String accessTokenValue; // string representation of the access token
044        private final String refreshTokenValue; // string representation of the refresh token
045        private transient JWT idToken; // this needs a custom serializer
046        private final String issuer; // issuer URL (parsed from the id token)
047        private final String sub; // user id (parsed from the id token)
048
049        private final UserInfo userInfo; // user info container
050
051        /**
052         * Constructs OIDCAuthenticationToken with a full set of authorities, marking this as authenticated.
053         *
054         * Set to authenticated.
055         *
056         * Constructs a Principal out of the subject and issuer.
057         * @param subject
058         * @param authorities
059         * @param principal
060         * @param idToken
061         */
062        public OIDCAuthenticationToken(String subject, String issuer,
063                        UserInfo userInfo, Collection<? extends GrantedAuthority> authorities,
064                        JWT idToken, String accessTokenValue, String refreshTokenValue) {
065
066                super(authorities);
067
068                this.principal = ImmutableMap.of("sub", subject, "iss", issuer);
069                this.userInfo = userInfo;
070                this.sub = subject;
071                this.issuer = issuer;
072                this.idToken = idToken;
073                this.accessTokenValue = accessTokenValue;
074                this.refreshTokenValue = refreshTokenValue;
075
076                setAuthenticated(true);
077        }
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 issuer
125         */
126        public String getIssuer() {
127                return issuer;
128        }
129
130        /**
131         * @return the userInfo
132         */
133        public UserInfo getUserInfo() {
134                return userInfo;
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}