keycloak-aplcache

Details

diff --git a/docbook/saml-adapter-docs/reference/en/en-US/master.xml b/docbook/saml-adapter-docs/reference/en/en-US/master.xml
index 6e88ed6..7f14165 100755
--- a/docbook/saml-adapter-docs/reference/en/en-US/master.xml
+++ b/docbook/saml-adapter-docs/reference/en/en-US/master.xml
@@ -8,6 +8,7 @@
                 <!ENTITY Jetty9Adapter SYSTEM "modules/jetty9-adapter.xml">
                 <!ENTITY Jetty8Adapter SYSTEM "modules/jetty8-adapter.xml">
                 <!ENTITY FilterAdapter SYSTEM "modules/servlet-filter-adapter.xml">
+                <!ENTITY Assertions SYSTEM "modules/assertion-api.xml">
                 <!ENTITY Logout SYSTEM "modules/logout.xml">
                 <!ENTITY ErrorHandling SYSTEM "modules/adapter_error_handling.xml">
                 ]>
@@ -50,6 +51,7 @@ This one is short
     &Jetty8Adapter;
     &FilterAdapter;
     &Logout;
+    &Assertions;
     &ErrorHandling;
 
 
diff --git a/docbook/saml-adapter-docs/reference/en/en-US/modules/assertion-api.xml b/docbook/saml-adapter-docs/reference/en/en-US/modules/assertion-api.xml
new file mode 100755
index 0000000..6106c07
--- /dev/null
+++ b/docbook/saml-adapter-docs/reference/en/en-US/modules/assertion-api.xml
@@ -0,0 +1,109 @@
+<chapter id="assertions">
+    <title>Obtaining Assertion Attributes</title>
+    <para>
+        After a successful SAML login, your application code may want to obtain attribute values passed with the SAML assertion.
+        <literal>HttpServletRequest.getUserPrincipal</literal> returns a Principal object that you can typecast into a
+        Keycloak specific class called <literal>org.keycloak.adapters.saml.SamlPrincipal</literal>.  This object allows
+        you to look at the raw assertion and also has convenience functions to look up attribute values.
+    </para>
+    <para>
+<programlisting><![CDATA[
+package org.keycloak.adapters.saml;
+
+public class SamlPrincipal implements Serializable, Principal {
+    /**
+     * Get full saml assertion
+     *
+     * @return
+     */
+    public AssertionType getAssertion() {
+       ...
+    }
+
+    /**
+     * Get SAML subject sent in assertion
+     *
+     * @return
+     */
+    public String getSamlSubject() {
+        ...
+    }
+
+    /**
+     * Subject nameID format
+     *
+     * @return
+     */
+    public String getNameIDFormat() {
+        ...
+    }
+
+    @Override
+    public String getName() {
+        ...
+    }
+
+    /**
+     * Convenience function that gets Attribute value by attribute name
+     *
+     * @param name
+     * @return
+     */
+    public List<String> getAttributes(String name) {
+        ...
+
+    }
+
+    /**
+     * Convenience function that gets Attribute value by attribute friendly name
+     *
+     * @param friendlyName
+     * @return
+     */
+    public List<String> getFriendlyAttributes(String friendlyName) {
+        ...
+    }
+
+    /**
+     * Convenience function that gets first  value of an attribute by attribute name
+     *
+     * @param name
+     * @return
+     */
+    public String getAttribute(String name) {
+        ...
+    }
+
+    /**
+     * Convenience function that gets first  value of an attribute by attribute name
+     *
+     *
+     * @param friendlyName
+     * @return
+     */
+    public String getFriendlyAttribute(String friendlyName) {
+        ...
+    }
+
+    /**
+     * Get set of all assertion attribute names
+     *
+     * @return
+     */
+    public Set<String> getAttributeNames() {
+        ...
+    }
+
+    /**
+     * Get set of all assertion friendly attribute names
+     *
+     * @return
+     */
+    public Set<String> getFriendlyNames() {
+        ...
+    }
+}
+]]>
+</programlisting>
+    </para>
+</chapter>
\ No newline at end of file
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
index 1d289d7..4c5f6a7 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java
@@ -377,7 +377,7 @@ public abstract class SamlAuthenticator {
 
         URI nameFormat = subjectNameID.getFormat();
         String nameFormatString = nameFormat == null ? JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get() : nameFormat.toString();
-        final SamlPrincipal principal = new SamlPrincipal(principalName, principalName, nameFormatString, attributes, friendlyAttributes);
+        final SamlPrincipal principal = new SamlPrincipal(assertion, principalName, principalName, nameFormatString, attributes, friendlyAttributes);
         String index = authn == null ? null : authn.getSessionIndex();
         final String sessionIndex = index;
         SamlSession account = new SamlSession(principal, roles, sessionIndex);
diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlPrincipal.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlPrincipal.java
index ef1599f..04c1c2f 100755
--- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlPrincipal.java
+++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlPrincipal.java
@@ -1,6 +1,7 @@
 package org.keycloak.adapters.saml;
 
 import org.keycloak.common.util.MultivaluedHashMap;
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
 
 import java.io.Serializable;
 import java.security.Principal;
@@ -18,22 +19,43 @@ public class SamlPrincipal implements Serializable, Principal {
     private String name;
     private String samlSubject;
     private String nameIDFormat;
+    private AssertionType assertion;
 
-    public SamlPrincipal(String name, String samlSubject, String nameIDFormat, MultivaluedHashMap<String, String> attributes, MultivaluedHashMap<String, String> friendlyAttributes) {
+    public SamlPrincipal(AssertionType assertion, String name, String samlSubject, String nameIDFormat, MultivaluedHashMap<String, String> attributes, MultivaluedHashMap<String, String> friendlyAttributes) {
         this.name = name;
         this.attributes = attributes;
         this.friendlyAttributes = friendlyAttributes;
         this.samlSubject = samlSubject;
         this.nameIDFormat = nameIDFormat;
+        this.assertion = assertion;
     }
 
     public SamlPrincipal() {
     }
 
+    /**
+     * Get full saml assertion
+     *
+     * @return
+     */
+    public AssertionType getAssertion() {
+        return assertion;
+    }
+
+    /**
+     * Get SAML subject sent in assertion
+     *
+     * @return
+     */
     public String getSamlSubject() {
         return samlSubject;
     }
 
+    /**
+     * Subject nameID format
+     *
+     * @return
+     */
     public String getNameIDFormat() {
         return nameIDFormat;
     }
@@ -43,7 +65,12 @@ public class SamlPrincipal implements Serializable, Principal {
         return name;
     }
 
-
+    /**
+     * Convenience function that gets Attribute value by attribute name
+     *
+     * @param name
+     * @return
+     */
     public List<String> getAttributes(String name) {
         List<String> list = attributes.get(name);
         if (list != null) {
@@ -53,6 +80,13 @@ public class SamlPrincipal implements Serializable, Principal {
         }
 
     }
+
+    /**
+     * Convenience function that gets Attribute value by attribute friendly name
+     *
+     * @param friendlyName
+     * @return
+     */
     public List<String> getFriendlyAttributes(String friendlyName) {
         List<String> list = friendlyAttributes.get(name);
         if (list != null) {
@@ -63,19 +97,42 @@ public class SamlPrincipal implements Serializable, Principal {
 
     }
 
+    /**
+     * Convenience function that gets first  value of an attribute by attribute name
+     *
+     * @param name
+     * @return
+     */
     public String getAttribute(String name) {
         return attributes.getFirst(name);
     }
 
+    /**
+     * Convenience function that gets first  value of an attribute by attribute name
+     *
+     *
+     * @param friendlyName
+     * @return
+     */
     public String getFriendlyAttribute(String friendlyName) {
         return friendlyAttributes.getFirst(friendlyName);
     }
 
+    /**
+     * Get set of all assertion attribute names
+     *
+     * @return
+     */
     public Set<String> getAttributeNames() {
         return Collections.unmodifiableSet(attributes.keySet());
 
     }
 
+    /**
+     * Get set of all assertion friendly attribute names
+     *
+     * @return
+     */
     public Set<String> getFriendlyNames() {
         return Collections.unmodifiableSet(friendlyAttributes.keySet());