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}