2014-10-30 3 views
0

Я разработал веб-приложение Java, и я хочу реализовать SAML. Это те шаги, которые я считаю правильным для реализации SAML.Создать ответ SAML на основе запроса SAML

  1. Поставщик услуг (SP, мое приложение в этом случае) отправляет запрос аутентификации SAML в IdP.
  2. IdP затем проверяет его и создает утверждение SAML-ответа и подписывает его сертификатом и отправляет обратно в SP.
  3. SP затем проверяет его с помощью открытого ключа сертификата в хранилище ключей и далее основывается на этом.

Я получил образец кода, и я могу создать запрос SAML, и его, как этот

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 
    ID="_c7b796f4-bc16-4fcc-8c1d-36befffc39c2" Version="2.0" 
    IssueInstant="2014-10-30T11:21:08Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" 
    AssertionConsumerServiceURL="http://localhost:8080/mywebapp/consume.jsp"> 
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8080/mywebapp 
    </saml:Issuer> 
    <samlp:NameIDPolicy 
     Format="urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified" 
     AllowCreate="true"></samlp:NameIDPolicy> 
    <samlp:RequestedAuthnContext Comparison="exact"> 
     <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport 
     </saml:AuthnContextClassRef> 
    </samlp:RequestedAuthnContext> 
</samlp:AuthnRequest> 

Я могу закодировать его и отправить IdP.

Я хочу создать образец кода Java, чтобы получить этот запрос SAML, а затем создать ответ SAML. Как я могу декодировать запрос и проверить его и создать ответ? И мне нужно подписать ответ saml с сертификатом? а затем отправить обратно в SP?

Спасибо.

ответ

2

Более точные шаги, которые вы указали. Единственное, на что я хотел бы обратить внимание, это то, что вы должны быть осторожны со значением, если слово отправляет (например, «SP ... отправляет запрос аутентификации SAML на IdP»). SAML позволяет сценарии аутентификации с нулевой прямой связью между SP и IdP.

Еще одно небольшое дополнение заключается в том, что SP также может подписывать свой запрос, поэтому вы можете иметь подпись с обеих сторон. Валидация на стороне СП обязательна.

Если вы хотите реализовать SAML, вы можете проверить одно из существующих решений, например Shibboleth. Если вы находитесь на таких платформах, как Spring и JBoss, вы можете проверить Spring Security SAML или JBoss PicketLink. Если вы хотите пойти на нижний уровень, отметьте OpenSAML.

В моем корпусе у нас есть JBoss в качестве стандарта, и мы очень довольны PicketLink.

+0

Я хочу проверить мое приложение. Я создал запрос SAML. Я пробовал с некоторыми IdP, но это не бесплатно. Поэтому я пытаюсь создать собственный ответ SAML. У меня есть образец сертификата. Я хочу подписать ответ и отправить заявку. – iUser

+0

Я думаю, вы можете протестировать с SalesForce бесплатно. Вот документ для PicketLink, но вы также можете применить его для своего SP: https://docs.jboss.org/author/display/PLINK/Picketlink+as+SP,+Salesforce+as+IDP – lexicore

+0

Как мы можем получить SAMLAssertion из SAMLResponse с использованием java-кода? –

5

Хотя это старый пост, я добавляю пример кода и ссылок, которые я нашел полезными.

SAMLResponse = hreq.getParameter("SAMLResponse"); 
InputSource inputSource = new InputSource(new StringReader(SAMLResponse)); 
SAMLReader samlReader = new SAMLReader();     
response2 = org.opensaml.saml2.core.Response)samlReader.readFromFile(inputSource); 

Теперь Утверждать цифровую подпись:

org.opensaml.saml2.core.Response response2 = (org.opensaml.saml2.core.Response)samlReader.readFromFile(inputSource); 
//To fetch the digital signature from the response. 
Signature signature = response2.getSignature(); 
X509Certificate certificate = (X509Certificate) keyStore.getCertificate(domainName); 
//pull out the public key part of the certificate into a KeySpec 
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(certificate.getPublicKey().getEncoded()); 
//get KeyFactory object that creates key objects, specifying RSA - java.security.KeyFactory 
KeyFactory keyFactory = KeyFactory.getInstance("RSA");     
//generate public key to validate signatures 
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); 
//we have the public key      
BasicX509Credential publicCredential = new BasicX509Credential(); 
//add public key value 
publicCredential.setPublicKey(publicKey); 
//create SignatureValidator 
SignatureValidator signatureValidator = new SignatureValidator(publicCredential); 
//try to validate 
try{ 
signatureValidator.validate(signature); 
catch(Exception e){ 
// 
} 

Теперь выборки карты утверждения:

samlDetailsMap = setSAMLDetails(response2); 

В приведенной выше логике использовании ниже частный способа вытащить все атрибуты утверждения. Наконец, у вас будет карта всех полей, отправленных вам.

private Map<String, String> setSAMLDetails(org.opensaml.saml2.core.Response response2){ 
     Map<String, String> samlDetailsMap = new HashMap<String, String>(); 
     try { 
      List<Assertion> assertions = response2.getAssertions(); 
      LOGGER.error("No of assertions : "+assertions.size()); 
      for(Assertion assertion:assertions){ 
       List<AttributeStatement> attributeStatements = assertion.getAttributeStatements(); 
       for(AttributeStatement attributeStatement: attributeStatements){ 
        List<Attribute> attributes = attributeStatement.getAttributes(); 
        for(Attribute attribute: attributes){ 
         String name = attribute.getName();       
         List<XMLObject> attributes1 = attribute.getAttributeValues(); 
         for(XMLObject xmlObject : attributes1){ 
          if(xmlObject instanceof XSString){ 
           samlDetailsMap.put(name, ((XSString) xmlObject).getValue()); 
           LOGGER.error("Name is : "+name+" value is : "+((XSString) xmlObject).getValue()); 
          }else if(xmlObject instanceof XSAnyImpl){ 
           String value = ((XSAnyImpl) xmlObject).getTextContent(); 

           samlDetailsMap.put(name, value); 

          }   
        } 
       } 
      }  
     } 
     } catch (Exception e) {    
      LOGGER.error("Exception occurred while setting the saml details");   
     }  
     LOGGER.error("Exiting from setSAMLDetails method"); 
     return samlDetailsMap; 
    } 

Добавить новый класс SAMLReader, как показано ниже:

import java.io.IOException; 
import java.io.InputStream; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 

import org.opensaml.DefaultBootstrap; 
import org.opensaml.xml.Configuration; 
import org.opensaml.xml.XMLObject; 
import org.opensaml.xml.io.UnmarshallingException; 
import org.w3c.dom.Element; 
import org.xml.sax.InputSource; 
import org.xml.sax.SAXException; 


public class SAMLReader { 

private static DocumentBuilder builder; 

static{ 
     try{ 
      DefaultBootstrap.bootstrap(); 
      DocumentBuilderFactory factory = 
        DocumentBuilderFactory.newInstance(); 
       factory.setNamespaceAware (true);   
      builder = factory.newDocumentBuilder(); 
     }catch (Exception ex){ 
      ex.printStackTrace(); 
     } 
    } 



/** 
* 
* @param filename 
* @return 
* @throws IOException 
* @throws UnmarshallingException 
* @throws SAXException 
*/ 
public XMLObject readFromFile (String filename) 
      throws IOException, UnmarshallingException, SAXException{ 
      return fromElement (builder.parse (filename).getDocumentElement());  
} 
/** 
*  
* @param is 
* @return 
* @throws IOException 
* @throws UnmarshallingException 
* @throws SAXException 
*/ 
public XMLObject readFromFile (InputStream is) 
       throws IOException, UnmarshallingException, SAXException{ 
       return fromElement (builder.parse (is).getDocumentElement());  
} 
/** 
*  
* @param is 
* @return 
* @throws IOException 
* @throws UnmarshallingException 
* @throws SAXException 
*/ 
public XMLObject readFromFile (InputSource is) 
       throws IOException, UnmarshallingException, SAXException{     
       return fromElement (builder.parse (is).getDocumentElement());  
} 

/** 
* 
* @param element 
* @return 
* @throws IOException 
* @throws UnmarshallingException 
* @throws SAXException 
*/ 
public static XMLObject fromElement (Element element) 
      throws IOException, UnmarshallingException, SAXException{ 
    return Configuration.getUnmarshallerFactory() 
       .getUnmarshaller (element).unmarshall (element);  
} 

}

 Смежные вопросы

  • Нет связанных вопросов^_^