Details
diff --git a/docbook/auth-server-docs/reference/en/en-US/master.xml b/docbook/auth-server-docs/reference/en/en-US/master.xml
index 95ff5ee..16a8601 100755
--- a/docbook/auth-server-docs/reference/en/en-US/master.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/master.xml
@@ -27,6 +27,7 @@
<!ENTITY Migration SYSTEM "modules/MigrationFromOlderVersions.xml">
<!ENTITY Email SYSTEM "modules/email.xml">
<!ENTITY Roles SYSTEM "modules/roles.xml">
+ <!ENTITY Groups SYSTEM "modules/groups.xml">
<!ENTITY DirectAccess SYSTEM "modules/direct-access.xml">
<!ENTITY ServiceAccounts SYSTEM "modules/service-accounts.xml">
<!ENTITY CORS SYSTEM "modules/cors.xml">
@@ -133,6 +134,7 @@ This one is short
</chapter>
&AccessTypes;
&Roles;
+ &Groups;
&DirectAccess;
&ServiceAccounts;
&CORS;
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/groups.xml b/docbook/auth-server-docs/reference/en/en-US/modules/groups.xml
new file mode 100755
index 0000000..eb54e0e
--- /dev/null
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/groups.xml
@@ -0,0 +1,31 @@
+<chapter id="groups">
+ <title>Groups</title>
+ <para>
+ Groups in Keycloak allow you to manage a common set of attributes and role mappings for a large set of users.
+ Users can be members of zero or more groups. Users inherit the attributes and role mappings assign to each group.
+ As an admin this makes it easy for you to manage permissions for a user in one place.
+ </para>
+ <para>
+ Groups are hierarchical. A group can have many subgroups, but a group can only have one parent. Subgroups inherit
+ the attributes and role mappings from the parent. This applies to user as well. So, if you have a parent group and a child group
+ and a user that only belongs to the child group, the user inherits the attributes and role mappings of both the
+ parent and child.
+ </para>
+ <section>
+ <title>Groups vs. Roles</title>
+ <para>
+ In the IT world the concepts of Group and Role are often blurred and interchangeable. In Keycloak, Groups are just
+ a collection of users that you can apply roles and attributes to in one place. Roles are used to assign permissions
+ and access control.
+ </para>
+ <para>
+ Keycloak Roles have the concept of a Composite Role. A role can be associated with one or more additional roles.
+ This is called a Composite Role. If a user has a role mapping to the Composite Role, they inherit all the roles associated
+ with the composite. So what's the difference from a Keycloak Group and a Composite Role? Logically they could be
+ used for the same exact thing. The difference is conceptual. Composite roles should be used to compose the
+ permission model of your set of services and applications. So, roles become a set of permissions. Groups on the
+ other hand, would be a set of users that have a set of permissions. Use Groups to manage users, composite roles to
+ manage applications and services.
+ </para>
+ </section>
+</chapter>
\ No newline at end of file
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/roles.xml b/docbook/auth-server-docs/reference/en/en-US/modules/roles.xml
index 9cd6176..b7c034c 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/roles.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/roles.xml
@@ -1,7 +1,7 @@
<chapter id="roles">
<title>Roles</title>
<para>
- In Keycloak, roles (or permissions) can be defined globally at the realm level, or individually per application.
+ In Keycloak, roles can be defined globally at the realm level, or individually per application.
Each role has a name which must be unique at the level it is defined in, i.e. you can have only one "admin" role at
the realm level. You may have that a role named "admin" within an Application too, but "admin" must be unique
for that application.
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 fb66a70..39f026a 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
@@ -22,6 +22,7 @@ import org.keycloak.saml.SAML2LogoutResponseBuilder;
import org.keycloak.saml.SAMLRequestParser;
import org.keycloak.saml.SignatureAlgorithm;
import org.keycloak.saml.common.constants.GeneralConstants;
+import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
import org.keycloak.saml.common.exceptions.ProcessingException;
import org.keycloak.saml.common.util.Base64;
import org.keycloak.saml.processing.api.saml.v2.sig.SAML2Signature;
@@ -33,6 +34,7 @@ import org.keycloak.common.util.MultivaluedHashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
+import java.net.URI;
import java.security.PublicKey;
import java.security.Signature;
import java.util.HashSet;
@@ -312,7 +314,9 @@ public abstract class SamlAuthenticator {
}
- final SamlPrincipal principal = new SamlPrincipal(principalName, principalName, subjectNameID.getFormat().toString(), attributes, friendlyAttributes);
+ 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);
String index = authn == null ? null : authn.getSessionIndex();
final String sessionIndex = index;
SamlSession account = new SamlSession(principal, roles, sessionIndex);