package org.jboss.seam.security.external.openid; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.List; import java.util.Map; import javax.enterprise.inject.Instance; import javax.enterprise.inject.Typed; import javax.inject.Inject; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletResponse; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import org.jboss.seam.security.external.EntityBean; import org.jboss.seam.security.external.JaxbContext; import org.jboss.seam.security.external.ResponseHandler; import org.jboss.seam.security.external.dialogues.api.Dialogued; import org.jboss.seam.security.external.jaxb.xrds.LocalID; import org.jboss.seam.security.external.jaxb.xrds.ObjectFactory; import org.jboss.seam.security.external.jaxb.xrds.Service; import org.jboss.seam.security.external.jaxb.xrds.Type; import org.jboss.seam.security.external.jaxb.xrds.URIPriorityAppendPattern; import org.jboss.seam.security.external.jaxb.xrds.XRD; import org.jboss.seam.security.external.jaxb.xrds.XRDS; import org.jboss.seam.security.external.spi.OpenIdProviderSpi; import org.openid4java.discovery.DiscoveryInformation; /** * @author Marcel Kolsteren */ @Typed(OpenIdProviderBean.class) public class OpenIdProviderBean extends EntityBean implements OpenIdProviderBeanApi { @Inject private Instance<OpenIdProviderRequest> openIdProviderRequest; @Inject private OpenIdProviderAuthenticationService openIdSingleLoginSender; @Inject private ServletContext servletContext; @Inject private Instance<OpenIdProviderSpi> openIdProviderSpi; @Inject @JaxbContext(ObjectFactory.class) private JAXBContext jaxbContext; @Inject private ResponseHandler responseHandler; public String getServiceURL(OpenIdService service) { String path = servletContext.getContextPath() + "/openid/OP/" + service.getName(); return createURL(path); } public String getRealm() { return createURL(""); } public String getXrdsURL() { return getServiceURL(OpenIdService.XRDS_SERVICE); } /** * Write XRDS with OP identifier (see OpenId 2.0 Authentication spec, section * 7.3.2.1.1.) * * @param writer writer to use */ public void writeOpIdentifierXrds(Writer writer) { try { ObjectFactory objectFactory = new ObjectFactory(); XRDS xrds = objectFactory.createXRDS(); XRD xrd = objectFactory.createXRD(); Type type = objectFactory.createType(); type.setValue(DiscoveryInformation.OPENID2_OP); URIPriorityAppendPattern uri = objectFactory.createURIPriorityAppendPattern(); uri.setValue(getServiceURL(OpenIdService.OPEN_ID_SERVICE)); Service service = objectFactory.createService(); service.getType().add(type); service.getURI().add(uri); xrd.getService().add(service); xrds.getOtherelement().add(xrd); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(xrds, writer); } catch (JAXBException e) { throw new RuntimeException(e); } } public void writeClaimedIdentifierXrds(Writer writer, String opLocalIdentifier) { try { ObjectFactory objectFactory = new ObjectFactory(); XRDS xrds = objectFactory.createXRDS(); XRD xrd = objectFactory.createXRD(); Type type = objectFactory.createType(); type.setValue(DiscoveryInformation.OPENID2); URIPriorityAppendPattern uri = objectFactory.createURIPriorityAppendPattern(); uri.setValue(getServiceURL(OpenIdService.OPEN_ID_SERVICE)); Service service = objectFactory.createService(); service.getType().add(type); service.getURI().add(uri); LocalID localId = new LocalID(); localId.setValue(opLocalIdentifier); service.getLocalID().add(localId); xrd.getService().add(service); xrds.getOtherelement().add(xrd); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(xrds, writer); } catch (JAXBException e) { throw new RuntimeException(e); } } public String getOpLocalIdentifierForUserName(String userName) { try { return createURL(getUsersPath() + URLEncoder.encode(userName, "UTF-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } public String getUserNameFromOpLocalIdentifier(String opLocalIdentifier) { String prefix = createURL(getUsersPath()); if (opLocalIdentifier.startsWith(prefix)) { String urlEncodedUserName = opLocalIdentifier.replace(prefix, ""); try { return URLDecoder.decode(urlEncodedUserName, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } else { return null; } } public String getUsersPath() { return servletContext.getContextPath() + "/users/"; } public String getUsersUrlPrefix() { return createURL(getUsersPath()); } @Dialogued(join = true) public void authenticationFailed(HttpServletResponse response) { openIdSingleLoginSender.sendAuthenticationResponse(false, null, response); } @Dialogued(join = true) public void authenticationSucceeded(String userName, HttpServletResponse response) { openIdProviderRequest.get().setUserName(userName); if (openIdProviderRequest.get().getRequestedAttributes() == null) { openIdSingleLoginSender.sendAuthenticationResponse(true, null, response); } else { openIdProviderSpi.get().fetchParameters(openIdProviderRequest.get().getRequestedAttributes(), responseHandler.createResponseHolder(response)); } } @Dialogued(join = true) public void setAttributes(Map<String, List<String>> attributeValues, HttpServletResponse response) { openIdSingleLoginSender.sendAuthenticationResponse(true, attributeValues, response); } }