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}