/**
* $Id: DefaultSAMLProvider.java,v 1.3 2008-06-02 14:50:12 langella Exp $
*
*/
package org.cagrid.gaards.authentication.service;
import gov.nih.nci.cagrid.common.Utils;
import gov.nih.nci.cagrid.opensaml.SAMLAssertion;
import gov.nih.nci.cagrid.opensaml.SAMLAttribute;
import gov.nih.nci.cagrid.opensaml.SAMLAttributeStatement;
import gov.nih.nci.cagrid.opensaml.SAMLAuthenticationStatement;
import gov.nih.nci.cagrid.opensaml.SAMLNameIdentifier;
import gov.nih.nci.cagrid.opensaml.SAMLSubject;
import gov.nih.nci.security.authentication.principal.EmailIdPrincipal;
import gov.nih.nci.security.authentication.principal.FirstNamePrincipal;
import gov.nih.nci.security.authentication.principal.LastNamePrincipal;
import gov.nih.nci.security.authentication.principal.LoginIdPrincipal;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.security.auth.Subject;
import javax.xml.namespace.QName;
import org.apache.xml.security.signature.XMLSignature;
import org.cagrid.gaards.authentication.common.InsufficientAttributeException;
import org.cagrid.gaards.pki.CertUtil;
import org.cagrid.gaards.pki.KeyUtil;
/**
*
* @version $Revision: 1.3 $
* @author Joshua Phillips
*
*/
public class DefaultSAMLProvider implements
org.cagrid.gaards.authentication.service.SAMLProvider {
private String certificateFileName;
private String privateKeyFileName;
private X509Certificate certificate;
private PrivateKey privateKey;
private String password;
public void loadCertificates(){
try{
File certFile = new File(getCertificateFileName());
if(!certFile.exists()){
throw new Exception("Certificate file not found at: " + certFile.getAbsolutePath());
}
Reader certReader = new FileReader(certFile);
X509Certificate cert = CertUtil.loadCertificate(certReader);
if(cert == null){
throw new Exception("Failed to load certificate.");
}
setCertificate(cert);
File keyFile = new File(getPrivateKeyFileName());
if(!keyFile.exists()){
throw new Exception("Private Key file not found at: " + keyFile.getAbsolutePath());
}
PrivateKey key = KeyUtil.loadPrivateKey(keyFile, Utils.clean(getPassword()));
if(key == null){
throw new Exception("Failed to load private key.");
}
setPrivateKey(key);
}catch(Exception ex){
throw new RuntimeException("Error loading certificates: " + ex.getMessage(), ex);
}
}
public X509Certificate getCertificate() {
return certificate;
}
public void setCertificate(X509Certificate certificate) {
this.certificate = certificate;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public PrivateKey getPrivateKey() {
return privateKey;
}
public void setPrivateKey(PrivateKey privateKey) {
this.privateKey = privateKey;
}
/* (non-Javadoc)
* @see gov.nih.nci.cagrid.authentication.common.SAMLProvider#getSAML(javax.security.auth.Subject)
*/
public SAMLAssertion getSAML(Subject subject)
throws InsufficientAttributeException {
//Get attributes
String uid = null;
String firstName = null;
String lastName = null;
String email = null;
Set principals = subject.getPrincipals();
Iterator it = principals.iterator();
while (it.hasNext()) {
Principal p = (Principal) it.next();
if(p instanceof LoginIdPrincipal){
uid = p.getName();
}else
if (p instanceof FirstNamePrincipal) {
firstName = p.getName();
}else
if (p instanceof LastNamePrincipal) {
lastName = p.getName();
}else
if (p instanceof EmailIdPrincipal) {
email = p.getName();
}
}
if (firstName == null || firstName.trim().length() < 1 || lastName == null || lastName.trim().length() < 1
|| email == null || email.trim().length() < 1) {
throw new InsufficientAttributeException(
"Missing attributes for the user");
}
SAMLAssertion saml = null;
try {
org.apache.xml.security.Init.init();
GregorianCalendar cal = new GregorianCalendar();
Date start = cal.getTime();
cal.add(Calendar.MINUTE, 2);
Date end = cal.getTime();
String issuer = this.certificate.getSubjectDN().toString();
String federation = this.certificate.getSubjectDN().toString();
String ipAddress = null;
String subjectDNS = null;
SAMLNameIdentifier ni1 = new SAMLNameIdentifier(uid, federation,
"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified");
SAMLSubject sub = new SAMLSubject(ni1, null, null, null);
sub.addConfirmationMethod(SAMLSubject.CONF_BEARER);
SAMLNameIdentifier ni2 = new SAMLNameIdentifier(uid, federation,
"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified");
SAMLSubject sub2 = new SAMLSubject(ni2, null, null, null);
sub2.addConfirmationMethod(SAMLSubject.CONF_BEARER);
SAMLAuthenticationStatement auth = new SAMLAuthenticationStatement(
sub, "urn:oasis:names:tc:SAML:1.0:am:unspecified", new Date(),
ipAddress, subjectDNS, null);
QName quid = new QName(SAMLConstants.UID_ATTRIBUTE_NAMESPACE,
SAMLConstants.UID_ATTRIBUTE);
List vals1 = new ArrayList();
vals1.add(uid);
SAMLAttribute uidAtt = new SAMLAttribute(quid.getLocalPart(), quid
.getNamespaceURI(), null, 0, vals1);
QName qfirst = new QName(
SAMLConstants.FIRST_NAME_ATTRIBUTE_NAMESPACE,
SAMLConstants.FIRST_NAME_ATTRIBUTE);
List vals2 = new ArrayList();
vals2.add(firstName);
SAMLAttribute firstNameAtt = new SAMLAttribute(qfirst
.getLocalPart(), qfirst.getNamespaceURI(), null, 0, vals2);
QName qLast = new QName(
SAMLConstants.LAST_NAME_ATTRIBUTE_NAMESPACE,
SAMLConstants.LAST_NAME_ATTRIBUTE);
List vals3 = new ArrayList();
vals3.add(lastName);
SAMLAttribute lastNameAtt = new SAMLAttribute(qLast.getLocalPart(),
qLast.getNamespaceURI(), null, 0, vals3);
QName qemail = new QName(SAMLConstants.EMAIL_ATTRIBUTE_NAMESPACE,
SAMLConstants.EMAIL_ATTRIBUTE);
List vals4 = new ArrayList();
vals4.add(email);
SAMLAttribute emailAtt = new SAMLAttribute(qemail.getLocalPart(),
qemail.getNamespaceURI(), null, 0, vals4);
List atts = new ArrayList();
atts.add(uidAtt);
atts.add(firstNameAtt);
atts.add(lastNameAtt);
atts.add(emailAtt);
SAMLAttributeStatement attState = new SAMLAttributeStatement(sub2,
atts);
List l = new ArrayList();
l.add(auth);
l.add(attState);
saml = new SAMLAssertion(issuer, start, end, null,
null, l);
List a = new ArrayList();
a.add(this.certificate);
saml.sign(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
this.privateKey, a);
} catch (Exception e) {
throw new RuntimeException(e);
}
return saml;
}
public String getCertificateFileName() {
return certificateFileName;
}
public void setCertificateFileName(String certificateFileName) {
this.certificateFileName = certificateFileName;
}
public String getPrivateKeyFileName() {
return privateKeyFileName;
}
public void setPrivateKeyFileName(String privateKeyFileName) {
this.privateKeyFileName = privateKeyFileName;
}
}