in gateway-provider-security-shiro/src/main/java/org/apache/knox/gateway/filter/ShiroSubjectIdentityAdapter.java [132:218]
public Void call() throws Exception {
PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
chain.doFilter( request, response );
return null;
}
};
Subject shiroSubject = SecurityUtils.getSubject();
/**
* For cases when we want anonymous authentication to urls in shiro.
* This is when do not want authentication for jwks endpoints using
* shiro.
*/
if (shiroSubject == null || shiroSubject.getPrincipal() == null) {
if(!isRequestPathInShiroConfig(((HttpServletRequest)request))) {
throw new IllegalStateException("Unable to determine authenticated user from Shiro, please check that your Knox Shiro configuration is correct");
}
LOG.unauthenticatedPathBypass(
((HttpServletRequest) request).getRequestURI());
final String principal = "anonymous";
javax.security.auth.Subject subject = new javax.security.auth.Subject();
subject.getPrincipals().add(new PrimaryPrincipal(principal));
AuditContext context = auditService.getContext();
context.setUsername(principal);
auditService.attachContext(context);
javax.security.auth.Subject.doAs(subject, action);
} else {
final String principal = shiroSubject.getPrincipal().toString();
Set<Principal> principals = new HashSet<>();
Principal p = new PrimaryPrincipal(principal);
principals.add(p);
AuditContext context = auditService.getContext();
context.setUsername(principal);
auditService.attachContext(context);
String sourceUri = (String) request.getAttribute(
AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME);
auditor.audit(Action.AUTHENTICATION, sourceUri, ResourceType.URI,
ActionOutcome.SUCCESS);
Set<String> userGroups;
// map ldap groups saved in session to Java Subject GroupPrincipal(s)
if (SecurityUtils.getSubject().getSession()
.getAttribute(SUBJECT_USER_GROUPS) != null) {
userGroups = (Set<String>) SecurityUtils.getSubject().getSession()
.getAttribute(SUBJECT_USER_GROUPS);
} else { // KnoxLdapRealm case
if (shiroSubject.getPrincipal() instanceof String) {
userGroups = new HashSet<>(shiroSubject.getPrincipals().asSet());
userGroups.remove(principal);
} else { // KnoxPamRealm case
Set<Principal> shiroPrincipals = new HashSet<>(
shiroSubject.getPrincipals().asSet());
userGroups = new HashSet<>(); // Here we are creating a new UserGroup
// so we don't need to remove a Principal
// In the case of LDAP the userGroup may have already Principal
// added to the list of groups, so it is not needed.
for (Principal shiroPrincipal : shiroPrincipals) {
userGroups.add(shiroPrincipal.toString());
}
}
}
for (String userGroup : userGroups) {
Principal gp = new GroupPrincipal(userGroup);
principals.add(gp);
}
auditor.audit(Action.AUTHENTICATION, sourceUri, ResourceType.URI,
ActionOutcome.SUCCESS, "Groups: " + userGroups);
// The newly constructed Sets check whether this Subject has been set read-only
// before permitting subsequent modifications. The newly created Sets also prevent
// illegal modifications by ensuring that callers have sufficient permissions.
//
// To modify the Principals Set, the caller must have AuthPermission("modifyPrincipals").
// To modify the public credential Set, the caller must have AuthPermission("modifyPublicCredentials").
// To modify the private credential Set, the caller must have AuthPermission("modifyPrivateCredentials").
javax.security.auth.Subject subject = new javax.security.auth.Subject(
true, principals, Collections.emptySet(), Collections.emptySet());
javax.security.auth.Subject.doAs(subject, action);
}
return null;
}