Skip to content

Commit

Permalink
waitFroCDI with sleep (ugly,testing) waiting for ServletContainerInit…
Browse files Browse the repository at this point in the history
…ializer ordering

commented web-fragment.xml ordering
ReflectionAndJaccCallerDetailsResolver Serializable
  • Loading branch information
pizzi80 committed Mar 1, 2022
1 parent 909ffbd commit 792a3d6
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 153 deletions.
3 changes: 2 additions & 1 deletion impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<parent>
<groupId>org.glassfish.soteria</groupId>
<artifactId>parent</artifactId>
<version>2.0.3-SNAPSHOT</version>
<version>2.0.4-SNAPSHOT</version>
</parent>

<artifactId>jakarta.security.enterprise</artifactId>
Expand Down Expand Up @@ -95,6 +95,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<source>11</source>
<target>11</target>
Expand Down
73 changes: 27 additions & 46 deletions impl/src/main/java/org/glassfish/soteria/authorization/JACC.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@

package org.glassfish.soteria.authorization;

import jakarta.security.jacc.*;
import jakarta.security.jacc.PolicyContext;
import jakarta.security.jacc.WebResourcePermission;
import jakarta.security.jacc.WebRoleRefPermission;

import javax.security.auth.Subject;
import java.security.*;
import java.security.cert.Certificate;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

import static java.security.Policy.getPolicy;
import static java.util.Collections.list;

public class JACC {
public enum JACC { INSTANCE;

public static String SUBJECT_CONTAINER_KEY = "javax.security.auth.Subject.container";
public static final String EMPTY = "";
public static final String SUBJECT_CONTAINER_KEY = "javax.security.auth.Subject.container";
public static final Principal[] EMPTY_PRINCIPALS = new Principal[0];

public static Subject getSubject() {
return getFromContext(SUBJECT_CONTAINER_KEY);
Expand All @@ -38,10 +41,8 @@ public static Subject getSubject() {
public static boolean isCallerInRole(String role) {

Subject subject = getSubject();

if (hasPermission(subject, new WebRoleRefPermission("", role))) {
return true;
}

return hasPermission( subject , new WebRoleRefPermission(EMPTY,role) );

// EJBContext ejbContext = getEJBContext();
//
Expand All @@ -61,8 +62,6 @@ public static boolean isCallerInRole(String role) {
// // ejbContext
// return ejbContext.isCallerInRole(role);
// }

return false;
}

public static boolean hasAccessToWebResource(String resource, String... methods) {
Expand All @@ -74,8 +73,8 @@ public static Set<String> getAllDeclaredCallerRoles() {
PermissionCollection permissionCollection = getPermissionCollection(getSubject());

// Resolve any potentially unresolved role permissions
permissionCollection.implies(new WebRoleRefPermission("", "nothing"));
permissionCollection.implies(new EJBRoleRefPermission("", "nothing"));
permissionCollection.implies(new WebRoleRefPermission(EMPTY, "nothing"));
//permissionCollection.implies(new EJBRoleRefPermission(EMPTY, "nothing")); // EJB Role ??

// Filter just the roles from all the permissions, which may include things like
// java.net.SocketPermission, java.io.FilePermission, and obtain the actual role names.
Expand All @@ -95,60 +94,42 @@ public static PermissionCollection getPermissionCollection(Subject subject) {
}

private static Policy getPolicyPrivileged() {
return (Policy) AccessController.doPrivileged(new PrivilegedAction<Policy>() {
public Policy run() {
return getPolicy();
}
});
return AccessController.doPrivileged( (PrivilegedAction<Policy>) () -> getPolicy() );
}

public static Set<String> filterRoles(PermissionCollection permissionCollection) {
Set<String> roles = new HashSet<>();
for (Permission permission : list(permissionCollection.elements())) {
if (isRolePermission(permission)) {
String role = permission.getActions();

// Note that the WebRoleRefPermission is given for every Servlet in the application, even when
// no role refs are used anywhere. This will also include Servlets like the default servlet and the
// implicit JSP servlet. So if there are 2 application roles, and 3 application servlets, then
// at least 6 WebRoleRefPermission elements will be present in the collection.
if (!roles.contains(role) && isCallerInRole(role)) {
roles.add(role);
}
}
}

return roles;
// Note that the WebRoleRefPermission is given for every Servlet in the application, even when
// no role refs are used anywhere. This will also include Servlets like the default servlet and the
// implicit JSP servlet. So if there are 2 application roles, and 3 application servlets, then
// at least 6 WebRoleRefPermission elements will be present in the collection.
return permissionCollection.elementsAsStream()
.filter(JACC::isRolePermission)
.map(Permission::getActions)
.filter(JACC::isCallerInRole)
.collect(Collectors.toSet());
}

public static ProtectionDomain fromSubject(Subject subject) {
Principal[] principals = subject != null ? subject.getPrincipals().toArray(new Principal[subject.getPrincipals().size()]) : new Principal[] {};

return new ProtectionDomain(
new CodeSource(null, (Certificate[]) null),
null, null,
principals
null,
null,
subject == null ? EMPTY_PRINCIPALS : subject.getPrincipals().toArray(EMPTY_PRINCIPALS)
);
}

@SuppressWarnings("unchecked")
public static <T> T getFromContext(String contextName) {
try {
T ctx = AccessController.doPrivileged(new PrivilegedExceptionAction<T>() {
public T run() throws PolicyContextException {
return (T) PolicyContext.getContext(contextName);
}
});
return ctx;
return AccessController.doPrivileged((PrivilegedExceptionAction<T>) () -> (T) PolicyContext.getContext(contextName));
} catch (PrivilegedActionException e) {
throw new IllegalStateException(e.getCause());
}
}

public static boolean isRolePermission(Permission permission) {
return permission instanceof WebRoleRefPermission || permission instanceof EJBRoleRefPermission;
return permission instanceof WebRoleRefPermission; // || permission instanceof EJBRoleRefPermission;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,38 @@
import org.glassfish.soteria.authorization.spi.CallerDetailsResolver;

import javax.security.auth.Subject;
import java.io.Serializable;
import java.security.Principal;
import java.util.List;
import java.util.Set;

import static java.util.Collections.emptyList;
import static jakarta.security.jacc.PolicyContext.getContextID;

public class ReflectionAndJaccCallerDetailsResolver implements CallerDetailsResolver {
public class ReflectionAndJaccCallerDetailsResolver implements CallerDetailsResolver , Serializable {

private static final long serialVersionUID = -6939132848715256303L;

@Override
public Principal getCallerPrincipal() {
Subject subject = JACC.getSubject();

if (subject == null) {
return null;
}
if (subject == null) return null;

SubjectParser subjectParser = new SubjectParser(getContextID(), emptyList());
SubjectParser subjectParser = new SubjectParser( getContextID() , List.of() );

return subjectParser.getCallerPrincipalFromPrincipals(subject.getPrincipals());
}

@Override
public <T extends Principal> Set<T> getPrincipalsByType(Class<T> pType) {
public <T extends Principal> Set<T> getPrincipalsByType(Class<T> principalType) {
Subject subject = JACC.getSubject();

if (subject == null) {
// Ensure behavior exactly matches that of Subject
// when returning an empty Set, and when pType == null.
subject = new Subject();
}
return subject.getPrincipals(pType);
return subject.getPrincipals(principalType);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,14 @@

package org.glassfish.soteria.servlet;

import static java.util.Collections.unmodifiableSet;

import java.io.Serializable;
import java.security.Principal;
import java.util.HashSet;
import java.util.Set;

/**
* This class holds stores "authentication data" (principal and groups).
*
* <p>
* This is intended as a temporary storage in the HTTP session for this data specifically
* This is intended as a temporary storage in the HTTP session for this data specifically
* during an HTTP redirect, which is why this class is in the servlet package.
*
* @author Arjan Tijms
Expand All @@ -41,7 +37,7 @@ public class AuthenticationData implements Serializable {

public AuthenticationData(Principal principal, Set<String> groups) {
this.principal = principal;
this.groups = unmodifiableSet(new HashSet<>(groups));
this.groups = Set.copyOf(groups);
}

public Principal getPrincipal() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,14 @@
import org.glassfish.soteria.Utils;


public class CookieHandler {
public enum CookieHandler { INSTANCE;

public static void saveCookie(HttpServletRequest request, HttpServletResponse response, String name, String value, Integer maxAge, boolean secureOnly, boolean HttpOnly) {
public static void saveCookie(HttpServletRequest request, HttpServletResponse response, String name, String value, Integer maxAge, boolean secureOnly, boolean httpOnly) {
Cookie cookie = new Cookie(name, value);
if (maxAge != null) {
cookie.setMaxAge(maxAge);
}
if (maxAge != null) cookie.setMaxAge(maxAge);
cookie.setSecure(secureOnly);
cookie.setHttpOnly(HttpOnly);
cookie.setPath(Utils.isEmpty(request.getContextPath())? "/" : request.getContextPath());
cookie.setHttpOnly(httpOnly);
cookie.setPath( Utils.isEmpty(request.getContextPath()) ? "/" : request.getContextPath() );

response.addCookie(cookie);
}
Expand Down
Loading

0 comments on commit 792a3d6

Please sign in to comment.