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());