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.web; 022 023import java.lang.reflect.Type; 024 025import javax.servlet.http.HttpServletRequest; 026import javax.servlet.http.HttpServletResponse; 027 028import org.mitre.openid.connect.model.OIDCAuthenticationToken; 029import org.mitre.openid.connect.model.UserInfo; 030import org.mitre.openid.connect.service.UserInfoService; 031import org.springframework.beans.factory.annotation.Autowired; 032import org.springframework.security.authentication.AuthenticationTrustResolver; 033import org.springframework.security.authentication.AuthenticationTrustResolverImpl; 034import org.springframework.security.core.Authentication; 035import org.springframework.security.core.GrantedAuthority; 036import org.springframework.security.core.context.SecurityContextHolder; 037import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 038 039import com.google.gson.Gson; 040import com.google.gson.GsonBuilder; 041import com.google.gson.JsonElement; 042import com.google.gson.JsonPrimitive; 043import com.google.gson.JsonSerializationContext; 044import com.google.gson.JsonSerializer; 045 046/** 047 * Injects the UserInfo object for the current user into the current model's context, if both exist. Allows JSPs and the like to call "userInfo.name" and other fields. 048 * 049 * @author jricher 050 * 051 */ 052public class UserInfoInterceptor extends HandlerInterceptorAdapter { 053 054 private Gson gson = new GsonBuilder() 055 .registerTypeHierarchyAdapter(GrantedAuthority.class, new JsonSerializer<GrantedAuthority>() { 056 @Override 057 public JsonElement serialize(GrantedAuthority src, Type typeOfSrc, JsonSerializationContext context) { 058 return new JsonPrimitive(src.getAuthority()); 059 } 060 }) 061 .create(); 062 063 @Autowired (required = false) 064 private UserInfoService userInfoService; 065 066 private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); 067 068 @Override 069 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 070 071 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 072 073 if (auth instanceof Authentication){ 074 request.setAttribute("userAuthorities", gson.toJson(auth.getAuthorities())); 075 } 076 077 if (!trustResolver.isAnonymous(auth)) { // skip lookup on anonymous logins 078 if (auth instanceof OIDCAuthenticationToken) { 079 // if they're logging into this server from a remote OIDC server, pass through their user info 080 OIDCAuthenticationToken oidc = (OIDCAuthenticationToken) auth; 081 if (oidc.getUserInfo() != null) { 082 request.setAttribute("userInfo", oidc.getUserInfo()); 083 request.setAttribute("userInfoJson", oidc.getUserInfo().toJson()); 084 } else { 085 request.setAttribute("userInfo", null); 086 request.setAttribute("userInfoJson", "null"); 087 } 088 } else { 089 // don't bother checking if we don't have a principal or a userInfoService to work with 090 if (auth != null && auth.getName() != null && userInfoService != null) { 091 092 // try to look up a user based on the principal's name 093 UserInfo user = userInfoService.getByUsername(auth.getName()); 094 095 // if we have one, inject it so views can use it 096 if (user != null) { 097 request.setAttribute("userInfo", user); 098 request.setAttribute("userInfoJson", user.toJson()); 099 } 100 } 101 } 102 } 103 104 return true; 105 } 106 107}