cleaned up userinfo view
parent
71d6dc6afe
commit
694761c026
|
@ -1,188 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright 2012 The MITRE Corporation
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.mitre.openid.connect.view;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.mitre.openid.connect.model.UserInfo;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.validation.BeanPropertyBindingResult;
|
|
||||||
import org.springframework.web.servlet.view.AbstractView;
|
|
||||||
|
|
||||||
import com.google.gson.ExclusionStrategy;
|
|
||||||
import com.google.gson.FieldAttributes;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
|
|
||||||
@Component("pocoUserInfoView")
|
|
||||||
public class POCOUserInfoView extends AbstractView {
|
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(POCOUserInfoView.class);
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
|
||||||
*/
|
|
||||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
|
|
||||||
UserInfo userInfo = (UserInfo) model.get("userInfo");
|
|
||||||
|
|
||||||
Set<String> scope = (Set<String>) model.get("scope");
|
|
||||||
|
|
||||||
Gson gson = new GsonBuilder()
|
|
||||||
.setExclusionStrategies(new ExclusionStrategy() {
|
|
||||||
|
|
||||||
public boolean shouldSkipField(FieldAttributes f) {
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldSkipClass(Class<?> clazz) {
|
|
||||||
// skip the JPA binding wrapper
|
|
||||||
if (clazz.equals(BeanPropertyBindingResult.class)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}).create();
|
|
||||||
|
|
||||||
response.setContentType("application/json");
|
|
||||||
|
|
||||||
Writer out;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
out = response.getWriter();
|
|
||||||
gson.toJson(toPoco(userInfo, scope), out);
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
|
|
||||||
logger.error("IOException in POCOUserInfoView.java: ", e);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonObject toPoco(UserInfo ui, Set<String> scope) {
|
|
||||||
JsonObject poco = new JsonObject();
|
|
||||||
|
|
||||||
// Envelope Info
|
|
||||||
poco.addProperty("startIndex", 0);
|
|
||||||
poco.addProperty("itemsPerPage", 1);
|
|
||||||
poco.addProperty("totalResults", 1);
|
|
||||||
|
|
||||||
// Build the entry for this userInfo, then add it to entries, then add it to poco
|
|
||||||
JsonObject entry = new JsonObject();
|
|
||||||
|
|
||||||
if (scope.contains("openid")) {
|
|
||||||
entry.addProperty("id", ui.getSub());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scope.contains("profile")) {
|
|
||||||
entry.addProperty("displayName", ui.getNickname());
|
|
||||||
|
|
||||||
if (ui.getFamilyName() != null
|
|
||||||
|| ui.getGivenName() != null
|
|
||||||
|| ui.getMiddleName() != null
|
|
||||||
|| ui.getName() != null) {
|
|
||||||
JsonObject name = new JsonObject();
|
|
||||||
name.addProperty("familyName", ui.getFamilyName());
|
|
||||||
name.addProperty("givenName", ui.getGivenName());
|
|
||||||
name.addProperty("middleName", ui.getMiddleName());
|
|
||||||
name.addProperty("formatted", ui.getName());
|
|
||||||
entry.add("name", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
entry.addProperty("gender", ui.getGender());
|
|
||||||
entry.addProperty("preferredUsername", ui.getPreferredUsername());
|
|
||||||
if (ui.getPicture() != null){
|
|
||||||
JsonObject photo = new JsonObject();
|
|
||||||
photo.addProperty("value", ui.getPicture());
|
|
||||||
|
|
||||||
JsonArray photoArray = new JsonArray();
|
|
||||||
photoArray.add(photo);
|
|
||||||
entry.add("photos", photoArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ui.getWebsite() != null) {
|
|
||||||
JsonObject website = new JsonObject();
|
|
||||||
website.addProperty("value", ui.getWebsite());
|
|
||||||
|
|
||||||
JsonArray websiteArray = new JsonArray();
|
|
||||||
websiteArray.add(website);
|
|
||||||
entry.add("urls", websiteArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
entry.addProperty("updated", ui.getUpdatedTime());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scope.contains("email")) {
|
|
||||||
if (ui.getEmail() != null) {
|
|
||||||
JsonObject email = new JsonObject();
|
|
||||||
email.addProperty("value", ui.getEmail());
|
|
||||||
|
|
||||||
JsonArray emailArray = new JsonArray();
|
|
||||||
emailArray.add(email);
|
|
||||||
entry.add("emails", emailArray);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scope.contains("phone")) {
|
|
||||||
if (ui.getPhoneNumber() != null){
|
|
||||||
JsonObject phone = new JsonObject();
|
|
||||||
phone.addProperty("value", ui.getPhoneNumber());
|
|
||||||
|
|
||||||
JsonArray phoneArray = new JsonArray();
|
|
||||||
phoneArray.add(phone);
|
|
||||||
entry.add("phoneNumbers", phoneArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scope.contains("address")) {
|
|
||||||
if (ui.getAddress() != null) {
|
|
||||||
JsonObject addr = new JsonObject();
|
|
||||||
addr.addProperty("formatted", ui.getAddress().getFormatted());
|
|
||||||
addr.addProperty("streetAddress", ui.getAddress().getStreetAddress());
|
|
||||||
addr.addProperty("locality", ui.getAddress().getLocality());
|
|
||||||
addr.addProperty("region", ui.getAddress().getRegion());
|
|
||||||
addr.addProperty("postalCode", ui.getAddress().getPostalCode());
|
|
||||||
addr.addProperty("country", ui.getAddress().getCountry());
|
|
||||||
|
|
||||||
JsonArray addrArray = new JsonArray();
|
|
||||||
addrArray.add(addr);
|
|
||||||
entry.add("addresses", addrArray);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonArray entryArray = new JsonArray();
|
|
||||||
entryArray.add(entry);
|
|
||||||
poco.add("entry", entryArray);
|
|
||||||
return poco;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -47,10 +47,10 @@ import com.google.gson.JsonSyntaxException;
|
||||||
import com.nimbusds.jwt.JWT;
|
import com.nimbusds.jwt.JWT;
|
||||||
import com.nimbusds.jwt.JWTParser;
|
import com.nimbusds.jwt.JWTParser;
|
||||||
|
|
||||||
@Component("jsonUserInfoView")
|
@Component("userInfoView")
|
||||||
public class JSONUserInfoView extends AbstractView {
|
public class UserInfoView extends AbstractView {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(JSONUserInfoView.class);
|
private static Logger logger = LoggerFactory.getLogger(UserInfoView.class);
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
* @see org.springframework.web.servlet.view.AbstractView#renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||||
|
@ -116,7 +116,7 @@ public class JSONUserInfoView extends AbstractView {
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
||||||
logger.error("IOException in JSONUserInfoView.java: ", e);
|
logger.error("IOException in UserInfoView.java: ", e);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,11 +199,15 @@ public class JSONUserInfoView extends AbstractView {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this mehod is likely to be fragile if the data model changes at all
|
||||||
|
|
||||||
//For each claim found, add it if not already present
|
//For each claim found, add it if not already present
|
||||||
for (Entry<String, JsonElement> i : claims.getAsJsonObject().entrySet()) {
|
for (Entry<String, JsonElement> i : claims.getAsJsonObject().entrySet()) {
|
||||||
String claimName = i.getKey();
|
String claimName = i.getKey();
|
||||||
if (!obj.has(claimName)) {
|
if (!obj.has(claimName)) {
|
||||||
String value = "";
|
String value = "";
|
||||||
|
|
||||||
|
|
||||||
//Process claim names to go from "claim_name" to "ClaimName"
|
//Process claim names to go from "claim_name" to "ClaimName"
|
||||||
String camelClaimName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, claimName);
|
String camelClaimName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, claimName);
|
||||||
//Now we have "getClaimName"
|
//Now we have "getClaimName"
|
|
@ -16,7 +16,6 @@
|
||||||
package org.mitre.openid.connect.web;
|
package org.mitre.openid.connect.web;
|
||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.mitre.openid.connect.exception.UnknownUserInfoSchemaException;
|
import org.mitre.openid.connect.exception.UnknownUserInfoSchemaException;
|
||||||
import org.mitre.openid.connect.exception.UserNotFoundException;
|
import org.mitre.openid.connect.exception.UserNotFoundException;
|
||||||
|
@ -33,9 +32,6 @@ import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OpenID Connect UserInfo endpoint, as specified in Standard sec 5 and Messages sec 2.4.
|
* OpenID Connect UserInfo endpoint, as specified in Standard sec 5 and Messages sec 2.4.
|
||||||
|
@ -51,17 +47,6 @@ public class UserInfoEndpoint {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(UserInfoEndpoint.class);
|
private static Logger logger = LoggerFactory.getLogger(UserInfoEndpoint.class);
|
||||||
|
|
||||||
private Map<String, String> schemaToViewNameMap = ImmutableMap.of(
|
|
||||||
openIdSchema, jsonUserInfoViewName,
|
|
||||||
pocoSchema, pocoUserInfoViewName
|
|
||||||
);
|
|
||||||
|
|
||||||
// Valid schemas and associated views
|
|
||||||
private static final String openIdSchema = "openid";
|
|
||||||
private static final String pocoSchema = "poco";
|
|
||||||
private static final String jsonUserInfoViewName = "jsonUserInfoView";
|
|
||||||
private static final String pocoUserInfoViewName = "pocoUserInfoView";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get information about the user as specified in the accessToken->idToken included in this request
|
* Get information about the user as specified in the accessToken->idToken included in this request
|
||||||
*
|
*
|
||||||
|
@ -71,7 +56,7 @@ public class UserInfoEndpoint {
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("hasRole('ROLE_USER') and #oauth2.hasScope('openid')")
|
@PreAuthorize("hasRole('ROLE_USER') and #oauth2.hasScope('openid')")
|
||||||
@RequestMapping(value="/userinfo", method= {RequestMethod.GET, RequestMethod.POST}, produces = "application/json")
|
@RequestMapping(value="/userinfo", method= {RequestMethod.GET, RequestMethod.POST}, produces = "application/json")
|
||||||
public String getInfo(Principal p, @RequestParam("schema") String schema, Model model) {
|
public String getInfo(Principal p, Model model) {
|
||||||
|
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
logger.error("getInfo failed; no principal. Requester is not authorized.");
|
logger.error("getInfo failed; no principal. Requester is not authorized.");
|
||||||
|
@ -79,13 +64,6 @@ public class UserInfoEndpoint {
|
||||||
return "httpCodeView";
|
return "httpCodeView";
|
||||||
}
|
}
|
||||||
|
|
||||||
String viewName = schemaToViewNameMap.get(schema);
|
|
||||||
if (viewName == null) {
|
|
||||||
logger.error("getInfo failed; unknown User Info schema " + schema);
|
|
||||||
model.addAttribute("code", HttpStatus.BAD_REQUEST);
|
|
||||||
return "httpCodeView";
|
|
||||||
}
|
|
||||||
|
|
||||||
String userId = p.getName();
|
String userId = p.getName();
|
||||||
UserInfo userInfo = userInfoService.getBySubject(userId);
|
UserInfo userInfo = userInfoService.getBySubject(userId);
|
||||||
|
|
||||||
|
@ -104,22 +82,8 @@ public class UserInfoEndpoint {
|
||||||
|
|
||||||
model.addAttribute("userInfo", userInfo);
|
model.addAttribute("userInfo", userInfo);
|
||||||
|
|
||||||
return viewName;
|
return "userInfoView";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the schemaToViewNameMap (defaults to an immutable map)
|
|
||||||
*/
|
|
||||||
public Map<String, String> getSchemaToViewNameMap() {
|
|
||||||
return schemaToViewNameMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param schemaToViewNameMap the schemaToViewNameMap to set
|
|
||||||
*/
|
|
||||||
public void setSchemaToViewNameMap(Map<String, String> schemaToViewNameMap) {
|
|
||||||
this.schemaToViewNameMap = schemaToViewNameMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue