Hello,
Just a heads up on this. After some debugging, I suspect there is an issue 
somewhere after the attributes get loaded into attribute repository. That's 
where List<Group> gets garbled into List<String> and because 
Group.toString() is not defined, the list gets filled with Java identifiers 
of Group instances. The SAML document release part of the flow receives 
already garbled data.

I upgraded to CAS 6.5 and this problem is solved there. Data structure 
correctly gets to the AbstractSamlObjectBuilder and you can even set the 
namespace, attributes, etc. by using Jackson annotations.
So the POJO in the attribute transform might look like this (example):

@JacksonXmlRootElement(namespace="somenamespace", localName="Group")
class Group {
    @JacksonXmlProperty(isAttribute = true)
    String attribute = "value";
    String element = "elementvalue";
    ...
}

The problem I am facing now seems to be in the AbstractSamlObjectBuilder 
which correctly builds the object, but pushes it to text content of the 
parent attribute. This means that output looks like:
&lt;Group xmlns=&quot;somenamespace&quot; 
attribute=&quot;value&quot;&gt;&lt;element&gt;elementvalue&lt;/element&gt;&lt;/Group&gt;
instead of:
<Group xmlns="somenamespace" 
attribute="value"><element>elementvalue</element></Group>

Cheers,
Fiisch
Dne čtvrtek 10. února 2022 v 17:14:21 UTC+1 uživatel Petr Fišer napsal:

> Hello,
> I am operating CAS 6.2.x as SAML2 IdP. One of our SP needs to get more 
> complex structure in the attribute statements, basically something like 
> this:
>
> <saml2:Attribute FriendlyName="groups" Name="groups" 
> NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
>     <saml2:AttributeValue>
>         <Group code="bla1" displayName="bla1"/>
>     </saml2:AttributeValue>
>     <saml2:AttributeValue>
>         <Group code="bla2" displayName="bla2"/>
>     </saml2:AttributeValue>
>     ...
> </saml2:Attribute>
>
> This should be possible by defining attribute "groups" with type XSObject 
> and CAS should then marshall it as a XML document inside the values. 
> https://apereo.github.io/cas/6.2.x/installation/Configuring-SAML2-Attribute-Release.html
> I am struggling in getting the setup to work... could somebody point me to 
> the right direction, please?
>
> Cheers,
>
> *The result i am getting:*
> <saml2:Attribute FriendlyName="groups" Name="groups" 
> NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
>     
> <saml2:AttributeValue>&lt;String&gt;Group@2abf08d0&lt;/String&gt;</saml2:AttributeValue>
>     
> <saml2:AttributeValue>&lt;String&gt;Group@86c9d74&lt;/String&gt;</saml2:AttributeValue>
>     
> <saml2:AttributeValue>&lt;String&gt;Group@5bdf462c&lt;/String&gt;</saml2:AttributeValue>
>     
> <saml2:AttributeValue>&lt;String&gt;Group@6715cd46&lt;/String&gt;</saml2:AttributeValue>
> </saml2:Attribute>
>
> *Part of CAS log:*
> 2022-02-10 14:09:36,169 TRACE 
> [org.apereo.cas.support.saml.util.AbstractSamlObjectBuilder] - <Attempting 
> to generate SAML attribute [groups] with value(s) [[Role@2abf08d0, 
> Group@86c9d74, Group@5bdf462c, Group@6715cd46]]>
> 2022-02-10 14:09:36,169 DEBUG 
> [org.apereo.cas.support.saml.util.AbstractSamlObjectBuilder] - <Generating 
> multi-valued SAML attribute [groups] with values [[Group@2abf08d0, 
> Group@86c9d74, Group@5bdf462c, Group@6715cd46]]>
> 2022-02-10 14:09:36,169 TRACE 
> [org.apereo.cas.support.saml.util.AbstractSamlObjectBuilder] - <Creating 
> new attribute value XMLObject for value: [Group@2abf08d0], value type: 
> [XSObject], QName: [{urn:oasis:names:tc:SAML:2.0:assertion}AttributeValue]>
> 2022-02-10 14:09:36,225 TRACE 
> [org.apereo.cas.support.saml.util.AbstractSamlObjectBuilder] - <Created 
> attribute value XMLObject: 
> [org.opensaml.core.xml.schema.impl.XSAnyImpl@a859946]>
> 2022-02-10 14:09:36,225 TRACE [org.opensaml.core.xml.AbstractXMLObject] - 
> <Releasing cached DOM reprsentation for parent of 
> {urn:oasis:names:tc:SAML:2.0:assertion}AttributeValue with propagation set 
> to true>
> 2022-02-10 14:09:36,225 TRACE [org.opensaml.core.xml.AbstractXMLObject] - 
> <Releasing cached DOM reprsentation for 
> {urn:oasis:names:tc:SAML:2.0:assertion}Attribute>
> 2022-02-10 14:09:36,225 TRACE [org.opensaml.core.xml.AbstractXMLObject] - 
> <Releasing cached DOM reprsentation for parent of 
> {urn:oasis:names:tc:SAML:2.0:assertion}Attribute with propagation set to 
> true>
>
> *My setup:*
> 1. LDAP server configured as attribute repository, each user has a 
> "memberOf" attribute. This works, CAS can see the "memberOf".
>
> 2. I have a set of attributes produced by CAS, defined at service level. 
> They are produced by inline groovy (works fine) with Mapped release policy.
>
> 3. Attribute "groups" produced by an external groovy script and GroovySaml 
> policy. This script takes "memberOf" and creates an array of custom objects 
> called Group. Script executes fine, but objects and not properly marshalled 
> into SAML response.
>
> *Relevant part of service definition:*
> "attributeReleasePolicy":
> {
> "@class": "org.apereo.cas.services.ChainingAttributeReleasePolicy",
> "mergingPolicy": "add",
> "policies": [ "java.util.ArrayList",
>   [
>     {
>   "@class": "org.apereo.cas.services.ReturnMappedAttributeReleasePolicy",
>   "allowedAttributes": {
>     "@class": "java.util.TreeMap",
>     "attr1": "groovy { return 'val1' }",
>     "attr2": "groovy { return 'val2' }"
>   },
>   "principalAttributesRepository":
>   {
>     "@class": 
> "org.apereo.cas.authentication.principal.DefaultPrincipalAttributesRepository",
>     "mergingStrategy": "MULTIVALUED",
>     "ignoreResolvedAttributes": false
>   }
> },
> {
>   "@class": 
> "org.apereo.cas.support.saml.services.GroovySamlRegisteredServiceAttributeReleasePolicy",
>   "groovyScript": "file:/etc/cas/config/groups-SAML.groovy",
>   "order": 1
>     }
>   ]
> ],
> "excludeDefaultAttributes": "true",
> "authorizedToReleaseAuthenticationAttributes": "false",
> "order": 0
> },
> "attributeValueTypes":
> {
> "@class": "java.util.LinkedHashMap",
> "groups": "XSObject"
> }
>
> *Relevant part of groups-SAML.groovy script:*
> def Map<String, Object> run(final Object... args) {
>     def attributes = args[0];
>     def service = args[1];
>     def resolver = args[2];
>     def facade = args[3];
>     def entityDescriptor = args[4];
>     def applicationContext = args[5];
>     def logger = args[6];
>
>     LinkedHashMap<String,Object> res = new LinkedHashMap<String,Object>();
>     ArrayList<Object> vals = new ArrayList<Object>();
>     for (o : attributes["memberOf"]) {
>         String s = parseName((String) o);
>         Group r = new Group(s);
>         vals.add(r);
>     }
>     res.put("groups",vals);
>
>     return res;
> }
>
> class Group extends XSAnyImpl {
>
>     private String textContent = null;
>     private LinkedHashMap<QName,String> unknownAttributes;
>     private IndexedXMLObjectChildrenList<XMLObject> unknownXMLObjects = 
> null;
>
>     public Group(String s) {
>         // 
> https://javadoc.io/static/org.opensaml/opensaml-core/3.4.3/org/opensaml/core/xml/schema/impl/XSAnyImpl.html
>         // 
> https://docs.oracle.com/javase/7/docs/api/javax/xml/namespace/QName.html?is-external=true
>         super("blablabla","Group",null);
>         this.unknownAttributes = new LinkedHashMap<QName,String>();
>         this.unknownAttributes.put(new QName("code"), s);
>         this.unknownAttributes.put(new QName("displayName"), s);
>     }
> }
>

-- 
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
--- 
You received this message because you are subscribed to the Google Groups "CAS 
Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to cas-user+unsubscr...@apereo.org.
To view this discussion on the web visit 
https://groups.google.com/a/apereo.org/d/msgid/cas-user/1bd46cde-ba6e-480e-8908-eacfba6fc6f4n%40apereo.org.

Reply via email to