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 6e88ed6e58..7f14165ab7 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 @@
+
]>
@@ -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 0000000000..6106c076a8
--- /dev/null
+++ b/docbook/saml-adapter-docs/reference/en/en-US/modules/assertion-api.xml
@@ -0,0 +1,109 @@
+
+ Obtaining Assertion Attributes
+
+ After a successful SAML login, your application code may want to obtain attribute values passed with the SAML assertion.
+ HttpServletRequest.getUserPrincipal returns a Principal object that you can typecast into a
+ Keycloak specific class called org.keycloak.adapters.saml.SamlPrincipal. This object allows
+ you to look at the raw assertion and also has convenience functions to look up attribute values.
+
+
+ getAttributes(String name) {
+ ...
+
+ }
+
+ /**
+ * Convenience function that gets Attribute value by attribute friendly name
+ *
+ * @param friendlyName
+ * @return
+ */
+ public List 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 getAttributeNames() {
+ ...
+ }
+
+ /**
+ * Get set of all assertion friendly attribute names
+ *
+ * @return
+ */
+ public Set getFriendlyNames() {
+ ...
+ }
+}
+]]>
+
+
+
\ 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 1d289d764e..4c5f6a7adf 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 ef1599f803..04c1c2fa2c 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 attributes, MultivaluedHashMap friendlyAttributes) {
+ public SamlPrincipal(AssertionType assertion, String name, String samlSubject, String nameIDFormat, MultivaluedHashMap attributes, MultivaluedHashMap 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 getAttributes(String name) {
List 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 getFriendlyAttributes(String friendlyName) {
List 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 getAttributeNames() {
return Collections.unmodifiableSet(attributes.keySet());
}
+ /**
+ * Get set of all assertion friendly attribute names
+ *
+ * @return
+ */
public Set getFriendlyNames() {
return Collections.unmodifiableSet(friendlyAttributes.keySet());