2013-03-19 75 views
1

我有一個應用程序已經有一個登錄系統和用戶對象等我想適應它,以便它可以使用SAML身份提供程序進行身份驗證。如何使用OpenSAML將用戶發送到SAML登錄頁面?

爲此,我需要構建一個頁面,將用戶發送到身份提供程序進行登錄。以下是我到目前爲止測試的內容:

public String getSamlLoginPage() throws IOException, ConfigurationException { 
    DefaultBootstrap.bootstrap(); 

    AuthnRequest authnRequest = buildSamlObject(AuthnRequest.DEFAULT_ELEMENT_NAME,AuthnRequestBuilder.class); 

    String myResponseUrl = "http://localhost:8080/samltest/saml?action=samlLogin"; 
    String serviceProviderEntityId = "someProviderEntityId"; 


    // set information in request 
    { 
     authnRequest.setForceAuthn(false); 
     authnRequest.setIsPassive(false); 
     authnRequest.setIssueInstant(new DateTime()); 
     authnRequest.setDestination(myResponseUrl); 
     authnRequest.setProtocolBinding(SAMLConstants.SAML2_ARTIFACT_BINDING_URI); 
     authnRequest.setAssertionConsumerServiceURL(myResponseUrl); 
     authnRequest.setID(""+UUID.randomUUID().getLeastSignificantBits()); 

     Issuer issuer = buildSamlObject(Issuer.DEFAULT_ELEMENT_NAME, IssuerBuilder.class); 
     issuer.setValue(serviceProviderEntityId); 
     authnRequest.setIssuer(issuer); 

     NameIDPolicy nameIDPolicy = buildSamlObject(NameIDPolicy.DEFAULT_ELEMENT_NAME, NameIDPolicyBuilder.class); 
     nameIDPolicy.setSPNameQualifier(serviceProviderEntityId); 
     nameIDPolicy.setAllowCreate(true); 
     nameIDPolicy.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:transient"); 
     authnRequest.setNameIDPolicy(nameIDPolicy); 

     RequestedAuthnContext requestedAuthnContext = buildSamlObject(RequestedAuthnContext.DEFAULT_ELEMENT_NAME,RequestedAuthnContextBuilder.class); 
     requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM); 

     AuthnContextClassRef authnContextClassRef = buildSamlObject(AuthnContextClassRef.DEFAULT_ELEMENT_NAME,AuthnContextClassRefBuilder.class); 
     authnContextClassRef.setAuthnContextClassRef("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"); 

     requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef); 
     authnRequest.setRequestedAuthnContext(requestedAuthnContext); 
    } 



    String samlRequestStr = XMLUtil.doc2String(authnRequest.getDOM()); 
    byte[] samlRequest = samlRequestStr.getBytes(); // <samlp:AuthnRequest> 

    ByteArrayOutputStream bout = new ByteArrayOutputStream(500); 
    Base64.encode(samlRequest,bout); 

    return 
     "<html><body>" 
     +"<form method=\"post\" action=\"https://idp.example.org/SAML2/SSO/POST\">" 
      +" <input type=\"hidden\" name=\"SAMLRequest\" value=\""+ bout.toString() +"\" />" 
//    +" <input type=\"hidden\" name=\"RelayState\" value=\"someToken\" />" 
      +" <input type=\"submit\" value=\"Submit\" />" 
      +" </form>" 
     +"<body></html>"; 
} 

private <SAMLObjectType extends SAMLObject, BuilderT extends SAMLObjectBuilder<SAMLObjectType>> SAMLObjectType buildSamlObject(javax.xml.namespace.QName defaultElementName, Class<BuilderT> type) { 
    XMLObjectBuilderFactory builderFactory = org.opensaml.Configuration.getBuilderFactory(); 
    BuilderT requestBuilder = (BuilderT)builderFactory.getBuilder(defaultElementName); 
    return requestBuilder.buildObject(); 
} 

我需要將操作更改爲指向實際身份提供者。除此之外,我應該把什麼東西放到Request對象中?我只需要身份提供者驗證用戶是真實用戶(他們將通過身份提供商的電子郵件和密碼登錄),然後告訴我他們的電子郵件地址是什麼以及我可以簽名的某種簽名驗證以證明用戶已被身份提供者驗證。

有關用戶的所有其他信息都存儲在本地,所以我只需要email和idp簽名。

+0

將用戶發送到登錄頁面後,您如何讓他輸入憑據並從idp中獲取saml響應? – Gobliins 2016-11-11 11:10:44

回答

0

saml請求必須包含幾件事情。它通常也必須簽名。 Here是我寫過的關於如何使用OpenSAML創建Authn SAML請求的博客文章。我也有一本書,A Guide to OpenSAML,它對SAML和OpenSAML庫有很好的介紹。

+0

我真的不知道這些字段是幹什麼的,但是我填寫了相同的字段並更新了我的問題中的代碼。 myResponseUrl的值只是響應將發佈到的url。我不知道serviceProviderEntityId應該有什麼價值。我沒有看到任何內容告訴idp在回覆中應將電子郵件地址退回給我。我做的有效嗎?我還需要投入什麼? – HappyEngineer 2013-03-20 20:37:15

+0

通常IDP決定返回什麼。 ServiceProviderEntityId是身份提供者的ID。整個身份聯合通常通過交換元數據開始,這是一個xml,其中包含有關每個終結點的信息。 ServiceProviderEntityId應該在那裏 – 2013-03-21 08:03:03

+0

我對SAML知之甚少,我建議你開始閱讀這個https://www.oasis-open.org/committees/download.php/27819/sstc-saml-tech-概述-2.0-CD-02.pdf – 2013-03-21 08:04:44

相關問題