Extending IPrincipal.IsInRole()
IsInRole()
I don't like how the method parameters are validated. IMO the null-propagation operator shouldn't be used for everything because it reduces the readability. Having a null-propagation operator for &quot;safely&quot; &quot;accessing&quot; a property is OK if the object is the first on the right hand of an assignment like in checking for var ident = principal?.Identity; but nevertheless I personally would stick to a combined null check like so
if (principal == null || principal.Identity == null) { return false; }  

But why areyou checking this at the beginning of the method ? I would check simple types first like departmentId &lt;= 0.
The null-propagation operator here
var roleDeparments = ((ClaimsIdentity)ident).FindFirst($&quot;{role} departments&quot;)?.Value;  

could be missed at first glance making a maintainer of the code wonder what this is about, at least if he/she has not that good eyes like me. He/she can't grasp at first glance that you &quot;safely&quot; access the Value property here.
Can you spot the error here ?
var inInRole = roleDeparments
    .Split(',')
    .Any(d =&gt; d == departmentId.ToString() || d == &quot;all&quot;);  

Aside from spelling error in inInRole you could store the result of departmentId.ToString() in a variable to check in the Any(), but maybe the compiler is smart enough to do this for you.
Omitting braces {} for single line if statemenst is your responsibility. I wouldn't do it. If I would do it then only like if (departmentId &lt;= 0) return false;
Using abbreviations leads to less readable code. Why don't you rename ident  to identity ?
Implementing the mentioned points leads to
public static bool IsInRole(this IPrincipal principal, string role, int departmentId)
{
    if (departmentId &lt;= 0) { return false; }
    if (principal == null || principal.Identity == null) { return false; }  
    
    var identity = principal.Identity;

    var claim = ((ClaimsIdentity)identity).FindFirst($&quot;{role} departments&quot;);
    if (claim == null) { return false; }
    
    var roleDeparments = claim.Value;
    if (string.IsNullOrWhiteSpace(roleDeparments)) { return false; }

    var isInRole = roleDeparments
        .Split(',')
        .Any(d =&gt; d == departmentId.ToString() || d == &quot;all&quot;);

    return isInRole;
}


CreateIdentity()
This made me wonder
bool isAll = departments.Any(d =&gt; d == null);  

reading isAll and Any. After rereading your question I stumbled over

if the departmentId is set to NULL then it means this role is general to all departments

This is screaming for a comment because a maintainer of the code should know this as well. Together with a better name it would be clear for a maintainer what is happening here like so
// If one of the user.UserRoles has a DepartmentId which is null,
// the role is general for all departments
bool isGeneralForAllDepartments = departments.Any(d =&gt; d == null);  

string departmentIds = isGeneralForAllDepartments 
    ? &quot;all&quot;
    : string.Join(&quot;,&quot;, departments);