added webfinger discovery to server, addresses #279

pull/324/merge
Justin Richer 2013-04-16 17:22:18 -04:00
parent 9c6b08d919
commit 895690df54
2 changed files with 156 additions and 15 deletions

View File

@ -0,0 +1,97 @@
/**
*
*/
package org.mitre.discovery.view;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mitre.openid.connect.view.JsonEntityView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
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;
/**
* @author jricher
*
*/
@Component("webfingerView")
public class WebfingerView extends AbstractView {
private static Logger logger = LoggerFactory.getLogger(WebfingerView.class);
private 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;
}
})
.serializeNulls()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
response.setContentType("application/jrd+json");
HttpStatus code = (HttpStatus) model.get("code");
if (code == null) {
code = HttpStatus.OK; // default to 200
}
response.setStatus(code.value());
try {
String resource = (String)model.get("resource");
String issuer = (String)model.get("issuer");
JsonObject obj = new JsonObject();
obj.addProperty("subject", resource);
JsonArray links = new JsonArray();
JsonObject link = new JsonObject();
link.addProperty("rel", "http://openid.net/specs/connect/1.0/issuer");
link.addProperty("href", issuer);
links.add(link);
obj.add("links", links);
Writer out = response.getWriter();
gson.toJson(obj, out);
} catch (IOException e) {
//TODO: Error Handling
logger.error("IOException in JsonEntityView.java: ", e);
}
}
}

View File

@ -15,21 +15,29 @@
******************************************************************************/ ******************************************************************************/
package org.mitre.discovery.web; package org.mitre.discovery.web;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
import org.mitre.oauth2.service.SystemScopeService; import org.mitre.oauth2.service.SystemScopeService;
import org.mitre.openid.connect.config.ConfigurationPropertiesBean; import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
import org.mitre.openid.connect.model.UserInfo;
import org.mitre.openid.connect.service.UserInfoService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller; 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.RequestParam;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.gson.JsonObject;
/** /**
* *
@ -52,20 +60,56 @@ public class DiscoveryEndpoint {
@Autowired @Autowired
private JwtSigningAndValidationService jwtService; private JwtSigningAndValidationService jwtService;
//TODO: rewrite, see issue #279, Webfinger @Autowired
// @RequestMapping(value={"/.well-known/host-meta", "/.well-known/host-meta.json"}, private UserInfoService userService;
// params={"resource", "rel=http://openid.net/specs/connect/1.0/issuer"}, produces = "application/json")
// public ModelAndView xrdDiscovery(@RequestParam("resource") String resource, ModelAndView modelAndView) { @RequestMapping(value={"/.well-known/webfinger"},
// params={"resource", "rel=http://openid.net/specs/connect/1.0/issuer"}, produces = "application/json")
// Map<String, String> relMap = new HashMap<String, String>(); public String webfinger(@RequestParam("resource") String resource, Model model) {
// relMap.put("http://openid.net/specs/connect/1.0/issuer", config.getIssuer());
// if (!resource.equals(config.getIssuer())) {
// modelAndView.getModel().put("links", relMap); // it's not the issuer directly, need to check other methods
//
// modelAndView.setViewName("jsonXrdResponseView"); try {
// URI resourceUri = new URI(resource);
// return modelAndView; if (resourceUri != null
// } && resourceUri.getScheme() != null
&& resourceUri.getScheme().equals("acct")) {
// acct: URI
// split out the user and host parts
List<String> parts = Lists.newArrayList(Splitter.on("@").split(resourceUri.getSchemeSpecificPart()));
UserInfo user = null;
if (parts.size() > 0) {
user = userService.getByUsername(parts.get(0)); // first part is the username
}
if (user == null) {
logger.info("User not found: " + resource);
model.addAttribute("code", HttpStatus.NOT_FOUND);
return "httpCodeView";
}
// TODO: check the "host" part against our issuer
} else {
logger.info("Unknown URI format: " + resource);
model.addAttribute("code", HttpStatus.NOT_FOUND);
return "httpCodeView";
}
} catch (URISyntaxException e) {
logger.info("URI parsing exception: " + resource, e);
model.addAttribute("code", HttpStatus.NOT_FOUND);
return "httpCodeView";
}
}
// if we got here, then we're good
model.addAttribute("resource", resource);
model.addAttribute("issuer", config.getIssuer());
return "webfingerView";
}
@RequestMapping("/.well-known/openid-configuration") @RequestMapping("/.well-known/openid-configuration")
public String providerConfiguration(Model model) { public String providerConfiguration(Model model) {