Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
This compensates for Grizzly's missing http auth via a servlet filter.
The test filter proxies the request, adding methods needed for authN, simulating container auth.
All BASIC login attempts will pass with test filter configured
The fedoraAdmin container role is assigned to any user named "fedoraAdmin"
New filter is configured in web.xml for http-api and auth-commons.
OAuth project has a similar filter that was tweaked to support more auth methods in a basic way.
OAuth project now configured to use the bypass security authentication provider for ITs

Fedora PEP interface for filtering searches was refactored around iterators instead of sets.

JAX-RS security contexts were stripped out of the ModeShape login chain, keeping login
at the container level. This also means that login can be based on Modeshape's standard
ServletCredentials object.

Renamed a constant representing the fedora user role, resulting in some one-line changes in other places
  • Loading branch information
gregjan authored and Andrew Woods committed Oct 4, 2013
1 parent 6291815 commit 80a6b9c
Show file tree
Hide file tree
Showing 15 changed files with 326 additions and 335 deletions.
Expand Up @@ -16,8 +16,6 @@

package org.fcrepo.auth;

import javax.servlet.http.HttpServletRequest;

import org.modeshape.jcr.ExecutionContext;
import org.modeshape.jcr.security.AuthorizationProvider;
import org.modeshape.jcr.security.SecurityContext;
Expand All @@ -26,20 +24,22 @@
/**
* This is a pass-through security context for authenticated Fedora
* administrators.
*
*
* @author Gregory Jansen
*/
public class FedoraAdminSecurityContext implements AuthorizationProvider,
SecurityContext {

private HttpServletRequest request = null;
private String username = null;

private boolean loggedIn = true;

/**
* @param request
*/
public FedoraAdminSecurityContext(final HttpServletRequest request) {
public FedoraAdminSecurityContext(final String username) {
super();
this.request = request;
this.username = username;
}

/*
Expand All @@ -48,7 +48,7 @@ public FedoraAdminSecurityContext(final HttpServletRequest request) {
*/
@Override
public boolean isAnonymous() {
return false;
return username != null;
}

/*
Expand All @@ -57,7 +57,7 @@ public boolean isAnonymous() {
*/
@Override
public String getUserName() {
return request.getRemoteUser();
return username;
}

/*
Expand All @@ -75,7 +75,7 @@ public boolean hasRole(final String roleName) {
*/
@Override
public void logout() {
request = null;
this.loggedIn = false;
}

/*
Expand All @@ -91,7 +91,7 @@ public boolean hasPermission(final ExecutionContext context,
final String repositoryName,
final String repositorySourceName, final String workspaceName,
final Path absPath, final String... actions) {
return request != null;
return this.loggedIn;
}

}
Expand Up @@ -17,7 +17,7 @@
package org.fcrepo.auth;

import java.security.Principal;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

import org.modeshape.jcr.value.Path;
Expand All @@ -26,15 +26,15 @@
* Policy Enforcement Points implement the various authorization decisions
* needed by Fedora. Implementations will translate enforcement calls into
* their given policy framework.
*
*
* @author Gregory Jansen
*/
public interface FedoraPolicyEnforcementPoint {

/**
* Is the action permitted to the user or other any other principal on the
* given node path?
*
*
* @param context
* @param absPath
* @param actions
Expand All @@ -49,12 +49,12 @@ public boolean hasModeShapePermission(Path absPath, String[] actions,
* Filter the collection of JCR paths, selecting those the user has
* permission to read.
*
* @param paths the collection of paths
* @param paths an iterator of paths
* @param allPrincipals all the authenticated principals
* @param userPrincipal the user principal
* @return set of permitted paths
* @return an iterator of permitted paths
*/
public Set<Path> filterPathsForReading(Collection<Path> paths,
public Iterator<Path> filterPathsForReading(Iterator<Path> paths,
Set<Principal> allPrincipals, Principal userPrincipal);

}
Expand Up @@ -17,11 +17,9 @@
package org.fcrepo.auth;

import java.security.Principal;
import java.util.Arrays;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.modeshape.jcr.api.ServletCredentials;
import org.modeshape.jcr.security.AdvancedAuthorizationProvider;
import org.modeshape.jcr.security.SecurityContext;
import org.modeshape.jcr.value.Path;
Expand All @@ -33,59 +31,71 @@
* necessarily authenticated by the container, i.e. users may include the
* general public. This security context delegates all access decisions to the
* configured Fedora policy enforcement point.
*
*
* @author Gregory Jansen
*/
public class FedoraUserSecurityContext implements SecurityContext,
AdvancedAuthorizationProvider {

private static Logger logger = LoggerFactory
private static Logger log = LoggerFactory
.getLogger(FedoraUserSecurityContext.class);

private Set<Principal> principals = null;

private HttpServletRequest request = null;
private Principal userPrincipal = null;

private ServletCredentials credentials = null;

private FedoraPolicyEnforcementPoint pep = null;

private boolean loggedIn = true;

/**
* Constructs a new security context.
*
*
* @param request the servlet request
* @param principals security principals associated with this request
* @param pep the policy enforcement point
*/
protected FedoraUserSecurityContext(final HttpServletRequest request,
protected FedoraUserSecurityContext(
final ServletCredentials credentials,
final Set<Principal> principals,
final FedoraPolicyEnforcementPoint pep) {
this.request = request;
this.credentials = credentials;
this.principals = principals;
this.pep = pep;
if (credentials.getRequest() != null) {
this.userPrincipal = credentials.getRequest().getUserPrincipal();
}
if (this.pep == null) {
log.warn("This security context must have a PEP injected");
throw new Error("This security context must have a PEP injected");
}
}

/**
* {@inheritDoc}
*
*
* @see org.modeshape.jcr.security.SecurityContext#isAnonymous()
*/
@Override
public boolean isAnonymous() {
return false;
return this.userPrincipal == null;
}

/**
* {@inheritDoc SecurityContext#getUserName()}
*
*
* @see SecurityContext#getUserName()
*/
@Override
public final String getUserName() {
return request.getRemoteUser();
return getEffectiveUserPrincipal().getName();
}

/**
* {@inheritDoc SecurityContext#hasRole(String)}
*
*
* @see SecurityContext#hasRole(String)
*/
@Override
Expand All @@ -100,26 +110,29 @@ public final boolean hasRole(final String roleName) {
return true;
}
return false;
// return request != null && request.isUserInRole(roleName);
}

/**
* Get the user principal associated with this context.
*
*
* @return
*/
public Principal getUserPrincipal() {
return this.request.getUserPrincipal();
public Principal getEffectiveUserPrincipal() {
if (this.loggedIn && this.userPrincipal != null) {
return this.userPrincipal;
} else {
return ServletContainerAuthenticationProvider.EVERYONE;
}
}

/**
* {@inheritDoc}
*
*
* @see org.modeshape.jcr.security.SecurityContext#logout()
*/
@Override
public void logout() {
request = null;
this.loggedIn = false;
}

/*
Expand All @@ -134,21 +147,11 @@ public void logout() {
* attributes: ??
*/
@Override
public boolean hasPermission(final Context context,
final Path absPath, final String... actions) {
logger.debug("in hasPermission");
// what roles do these principals have in repo (MODE-1920)
// final Privilege[] privs =
// context.getSession().getAccessControlManager()
// .getPrivileges(absPath.toString());
// final AccessControlPolicy[] policies =
// context.getSession().getAccessControlManager()
// .getEffectivePolicies(absPath.toString());
// policies[0].getClass();

logger.debug("hasPermission(" + context + "," +
(absPath == null ? absPath : absPath.getString()) + "," +
Arrays.toString(actions) + ")");
public boolean hasPermission(final Context context, final Path absPath,
final String... actions) {
if (!this.loggedIn) {
return false;
}

// this permission is required for login
if (absPath == null) {
Expand All @@ -158,9 +161,9 @@ public boolean hasPermission(final Context context,
// delegate to Fedora PDP
if (pep != null) {
return pep.hasModeShapePermission(absPath, actions,
this.principals, getUserPrincipal());
this.principals, getEffectiveUserPrincipal());
} else {
return true;
return false;
}
}
}

0 comments on commit 80a6b9c

Please sign in to comment.