I also had similar issues, and debugging mostly helped me figure out what to do.
I succeeded to make it work, but during that I found a bug in picketlink, fixed it, it still didn't work, and then I found the correct way to configure things (at least I believe it is the correct way :-) ). I'm not sure if the fix I did is still required after doing the configuration right, but I had another urgent issue so I didn't get a chance to test it. Feel free to test with and without the fix. I'll be happy to hear the results.
The steps I did:
1. You should take the fix Anil mentioned in the earlier comment.
2. Do the following fix as well in SAML2AttributeHandler.java:
@Override
public void initChainConfig(SAML2HandlerChainConfig handlerChainConfig) throws ConfigurationException
{
super.initChainConfig(handlerChainConfig);
Object config = this.handlerChainConfig.getParameter(GeneralConstants.CONFIGURATION);
if (config instanceof IDPType)
{
if ( attribManager == null ) { // ADD THIS IF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
IDPType idpType = (IDPType) config;
String attribStr = idpType.getAttributeManager();
insantiateAttributeManager(attribStr);
}
}
}
As I saw that the attribute manager is set again, although it is already set, and instead of using my attribute manager inside the DelegateAttributeManager, it uses TomcatAttributeManager... Again, this fix might not be needed if you configure things as below, but I'm not sure:
3. In picketlink-idfed.xml file, in the IDP:
I also had similar issues, and debugging mostly helped me figure out what to do.
I succeeded to make it work, but during that I found a bug in picketlink, fixed it, it still didn't work, and then I found the correct way to configure things (at least I believe it is the correct way :-) ). I'm not sure if the fix I did is still required after doing the configuration right, but I had another urgent issue so I didn't get a chance to test it. Feel free to test with and without the fix. I'll be happy to hear the results.
The steps I did:
1. You should take the fix Anil mentioned in the earlier comment.
2. Do the following fix as well in SAML2AttributeHandler.java:
@Override
public void initChainConfig(SAML2HandlerChainConfig handlerChainConfig) throws ConfigurationException
{
super.initChainConfig(handlerChainConfig);
Object config = this.handlerChainConfig.getParameter(GeneralConstants.CONFIGURATION);
if (config instanceof IDPType)
{
if ( attribManager == null ) { // ADD THIS IF!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
IDPType idpType = (IDPType) config;
String attribStr = idpType.getAttributeManager();
insantiateAttributeManager(attribStr);
}
}
}
As I saw that the attribute manager is set again, although it is already set, and instead of using my attribute manager inside the DelegateAttributeManager, it uses TomcatAttributeManager... Again, this fix might not be needed if you configure things as below, but I'm not sure:
3. In picketlink-idfed.xml file, in the IDP:
<PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:1.0" AttributeManager="engine.loginutils.EngineAttributeManager">
<IdentityURL>${idp.url::http://localhost:8080/idp/}</IdentityURL>
<Trust>
.... put things in if you need them. I didn't use this yet.
</Trust>
</PicketLinkIDP>
4. context.xml (IDP) - sessionID is the attribute I need:
<Context>
<Valve
className="org.picketlink.identity.federation.bindings.tomcat.idp.IDPWebBrowserSSOValve"
attributeList="sessionID"
ignoreAttributesGeneration="false"
signOutgoingMessages="false"
ignoreIncomingSignatures="true"/>
</Context>
5. jboss-web.xml (IDP) - put both attribute list and ignoreAttributeGeneration to false. Looks important, although didn't find documentation saying it is needed to get the attribute handler to work.
<jboss-web>
<security-domain>idp</security-domain>
<valve>
<class-name>org.picketlink.identity.federation.bindings.tomcat.idp.IDPWebBrowserSSOValve</class-name>
<param>
<param-name>signOutgoingMessages</param-name>
<param-value>false</param-value>
</param>
<param>
<param-name>ignoreIncomingSignatures</param-name>
<param-value>true</param-value>
</param>
<param>
<param-name>attributeList</param-name>
<param-value>sessionID</param-value>
</param>
<param>
<param-name>ignoreAttributesGeneration</param-name>
<param-value>false</param-value>
</param>
</valve>
</jboss-web>
6. picketlink-handlers.xml (IDP)
<Handlers xmlns="urn:picketlink:identity-federation:handler:config:1.0">
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2IssuerTrustHandler"/>
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler"/>
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler"/>
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AttributeHandler">
<Option Key="ATTRIBUTE_MANAGER" Value="engine.loginutils.EngineAttributeManager"/>
<Option Key="ATTRIBUTE_KEYS" Value="sessionID"/>
</Handler>
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler"/>
</Handlers>
7. picketlink-handlers (SP):
<Handlers xmlns="urn:picketlink:identity-federation:handler:config:1.0">
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler"/>
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler"/>
<Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AttributeHandler">
<Option Key="ATTRIBUTE_CHOOSE_FRIENDLY_NAME" Value="true"/>
</Handler>
</Handlers>
Code samples:
1. My login module, I set the attribute in the login method:
| HttpServletRequest request = (HttpServletRequest) javax.security.jacc.PolicyContext.getContext("javax.servlet.http.HttpServletRequest"); |
| sessionID = request.getSession().getId(); |
| Map<String, Object> attributes = new HashMap<String, Object>(); |
| attributes.put("sessionID", sessionID); |
| request.getSession().setAttribute("ATTRIBUTES", attributes); |
2. The AttributeManager:
public class EngineAttributeManager implements AttributeManager {
public Map<String, Object> getAttributes(Principal userPrincipal, List<String> attributeKeys) {
Map<String,Object> attributes = new HashMap<String, Object>();
HttpServletRequest request;
try {
request = (HttpServletRequest) javax.security.jacc.PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
HttpSession session = request.getSession();
Object customAttributes = session.getAttribute("ATTRIBUTES");
if ( customAttributes != null ) {
Map<String, Object> attributesMap = (Map<String, Object>) customAttributes;
for ( String key : attributeKeys ) {
Object attribute = attributesMap.get(key);
if ( attribute != null) {
attributes.put(key, attribute);
}
}
}
} catch (PolicyContextException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return attributes;
}
}
3. The SP code:
| private String getAuthenticationSession(HttpServletRequest req) { |
| String sessionID = null; |
| Object customAttributes = req.getSession().getAttribute("SESSION_ATTRIBUTE_MAP"); |
| if ( customAttributes != null ) { |
| Map<String, Object> attributesMap = (Map<String, Object>) customAttributes; |
| List<Object> sessionIDEntry = (List<Object>) attributesMap.get("sessionID"); |
| if ( sessionIDEntry != null ) { |
| sessionID = (String) sessionIDEntry.get(0); |
| } |
| } |
| return sessionID; |
| } |
Some questions due to the steps above:
1. Why do we need to define the attribute manager in 2 locations? The attribute list in 3 locations? Is it really needed?
2. Is the patch in "2" really needed?
3. Basically, if someone will provide the exact steps to make things work that would be great, as maybe some of the steps I did are redundant.
Again, as I said I didn't get a chance to start over and check exactly what's needed to make it work. It worked for me with this configuration.
Hope it is helpful.
Let me know if you test it deeper, and find out that things should be configured differently.
Oved