Skip to content

Commit

Permalink
multiprofile for authorizer
Browse files Browse the repository at this point in the history
  • Loading branch information
leleuj committed Mar 9, 2016
1 parent 165dd0d commit 677284b
Show file tree
Hide file tree
Showing 24 changed files with 364 additions and 147 deletions.
Expand Up @@ -12,7 +12,7 @@
public abstract class AbstractRequireAllAuthorizer<E extends Object, U extends UserProfile> extends AbstractRequireElementAuthorizer<E, U> { public abstract class AbstractRequireAllAuthorizer<E extends Object, U extends UserProfile> extends AbstractRequireElementAuthorizer<E, U> {


@Override @Override
public boolean isAuthorized(final WebContext context, final U profile) { protected boolean isProfileAuthorized(final WebContext context, final U profile) {
if (elements == null || elements.isEmpty()) { if (elements == null || elements.isEmpty()) {
return true; return true;
} }
Expand Down
Expand Up @@ -12,7 +12,7 @@
public abstract class AbstractRequireAnyAuthorizer<E extends Object, U extends UserProfile> extends AbstractRequireElementAuthorizer<E, U> { public abstract class AbstractRequireAnyAuthorizer<E extends Object, U extends UserProfile> extends AbstractRequireElementAuthorizer<E, U> {


@Override @Override
public boolean isAuthorized(final WebContext context, final U profile) { protected boolean isProfileAuthorized(final WebContext context, final U profile) {
if (elements == null || elements.isEmpty()) { if (elements == null || elements.isEmpty()) {
return true; return true;
} }
Expand Down
Expand Up @@ -14,7 +14,7 @@
* @author Jerome Leleu * @author Jerome Leleu
* @since 1.8.1 * @since 1.8.1
*/ */
public abstract class AbstractRequireElementAuthorizer<E extends Object, U extends UserProfile> implements Authorizer<U> { public abstract class AbstractRequireElementAuthorizer<E extends Object, U extends UserProfile> extends SingleProfileAuthorizer<U> {


protected Set<E> elements; protected Set<E> elements;


Expand Down
Expand Up @@ -3,6 +3,8 @@
import org.pac4j.core.context.WebContext; import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.UserProfile; import org.pac4j.core.profile.UserProfile;


import java.util.List;

/** /**
* Checks if an access is authorized. * Checks if an access is authorized.
* *
Expand All @@ -12,11 +14,11 @@
public interface Authorizer<U extends UserProfile> { public interface Authorizer<U extends UserProfile> {


/** /**
* Checks if the user profile is authorized for the current web context. * Checks if the user profiles and / or the current web context are authorized.
* *
* @param context the web context * @param context the web context
* @param profile the user profile * @param profiles the user profiles
* @return if the access is authorized * @return if the access is authorized
*/ */
boolean isAuthorized(WebContext context, U profile); boolean isAuthorized(WebContext context, List<U> profiles);
} }
Expand Up @@ -3,6 +3,8 @@
import org.pac4j.core.context.WebContext; import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.UserProfile; import org.pac4j.core.profile.UserProfile;


import java.util.List;

/** /**
* Cache control header. * Cache control header.
* *
Expand All @@ -12,7 +14,7 @@
public class CacheControlHeader implements Authorizer<UserProfile> { public class CacheControlHeader implements Authorizer<UserProfile> {


@Override @Override
public boolean isAuthorized(final WebContext context, final UserProfile profile) { public boolean isAuthorized(final WebContext context, final List<UserProfile> profiles) {
final String url = context.getFullRequestURL().toLowerCase(); final String url = context.getFullRequestURL().toLowerCase();
if (!url.endsWith(".css") if (!url.endsWith(".css")
&& !url.endsWith(".js") && !url.endsWith(".js")
Expand Down
@@ -0,0 +1,27 @@
package org.pac4j.core.authorization.authorizer;

import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.UserProfile;

import java.util.List;

/**
* Authorizer which is valid if one of the profile is authorized.
*
* @author Jerome Leleu
* @since 1.9.0
*/
public abstract class SingleProfileAuthorizer<U extends UserProfile> implements Authorizer<U> {

@Override
public boolean isAuthorized(final WebContext context, final List<U> profiles) {
for (final U profile : profiles) {
if (isProfileAuthorized(context, profile)) {
return true;
}
}
return false;
}

protected abstract boolean isProfileAuthorized(final WebContext context, final U profile);
}
Expand Up @@ -4,6 +4,8 @@
import org.pac4j.core.context.WebContext; import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.UserProfile; import org.pac4j.core.profile.UserProfile;


import java.util.List;

/** /**
* Strict transport security header. * Strict transport security header.
* *
Expand All @@ -26,7 +28,7 @@ public StrictTransportSecurityHeader(final int maxAge) {
} }


@Override @Override
public boolean isAuthorized(final WebContext context, final UserProfile profile) { public boolean isAuthorized(final WebContext context, final List<UserProfile> profiles) {
if (ContextHelper.isHttpsOrSecure(context)) { if (ContextHelper.isHttpsOrSecure(context)) {
context.setResponseHeader("Strict-Transport-Security", "max-age=" + maxAge + " ; includeSubDomains"); context.setResponseHeader("Strict-Transport-Security", "max-age=" + maxAge + " ; includeSubDomains");
} }
Expand Down
Expand Up @@ -3,6 +3,8 @@
import org.pac4j.core.context.WebContext; import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.UserProfile; import org.pac4j.core.profile.UserProfile;


import java.util.List;

/** /**
* XContent type options header. * XContent type options header.
* *
Expand All @@ -12,7 +14,7 @@
public class XContentTypeOptionsHeader implements Authorizer<UserProfile> { public class XContentTypeOptionsHeader implements Authorizer<UserProfile> {


@Override @Override
public boolean isAuthorized(final WebContext context, final UserProfile profile) { public boolean isAuthorized(final WebContext context, final List<UserProfile> profiles) {
context.setResponseHeader("X-Content-Type-Options", "nosniff"); context.setResponseHeader("X-Content-Type-Options", "nosniff");
return true; return true;
} }
Expand Down
Expand Up @@ -3,6 +3,8 @@
import org.pac4j.core.context.WebContext; import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.UserProfile; import org.pac4j.core.profile.UserProfile;


import java.util.List;

/** /**
* XFrame options header. * XFrame options header.
* *
Expand All @@ -12,7 +14,7 @@
public class XFrameOptionsHeader implements Authorizer<UserProfile> { public class XFrameOptionsHeader implements Authorizer<UserProfile> {


@Override @Override
public boolean isAuthorized(final WebContext context, final UserProfile profile) { public boolean isAuthorized(final WebContext context, final List<UserProfile> profiles) {
context.setResponseHeader("X-Frame-Options", "DENY"); context.setResponseHeader("X-Frame-Options", "DENY");
return true; return true;
} }
Expand Down
Expand Up @@ -3,6 +3,8 @@
import org.pac4j.core.context.WebContext; import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.UserProfile; import org.pac4j.core.profile.UserProfile;


import java.util.List;

/** /**
* XSS protection header. * XSS protection header.
* *
Expand All @@ -12,7 +14,7 @@
public class XSSProtectionHeader implements Authorizer<UserProfile> { public class XSSProtectionHeader implements Authorizer<UserProfile> {


@Override @Override
public boolean isAuthorized(final WebContext context, final UserProfile profile) { public boolean isAuthorized(final WebContext context, final List<UserProfile> profiles) {
context.setResponseHeader("X-XSS-Protection", "1; mode=block"); context.setResponseHeader("X-XSS-Protection", "1; mode=block");
return true; return true;
} }
Expand Down
Expand Up @@ -7,6 +7,8 @@
import org.pac4j.core.profile.UserProfile; import org.pac4j.core.profile.UserProfile;
import org.pac4j.core.util.CommonHelper; import org.pac4j.core.util.CommonHelper;


import java.util.List;

/** /**
* Authorizer that checks CSRF tokens. * Authorizer that checks CSRF tokens.
* *
Expand Down Expand Up @@ -35,7 +37,7 @@ public CsrfAuthorizer(final String parameterName, final String headerName, final
} }


@Override @Override
public boolean isAuthorized(final WebContext context, final U profile) { public boolean isAuthorized(final WebContext context, final List<U> profiles) {
final boolean checkRequest = !onlyCheckPostRequest || (onlyCheckPostRequest && ContextHelper.isPost(context)); final boolean checkRequest = !onlyCheckPostRequest || (onlyCheckPostRequest && ContextHelper.isPost(context));
if (checkRequest) { if (checkRequest) {
final String parameterToken = context.getRequestParameter(parameterName); final String parameterToken = context.getRequestParameter(parameterName);
Expand Down
Expand Up @@ -7,6 +7,8 @@
import org.pac4j.core.profile.UserProfile; import org.pac4j.core.profile.UserProfile;
import org.pac4j.core.util.CommonHelper; import org.pac4j.core.util.CommonHelper;


import java.util.List;

/** /**
* Authorizer which creates a new CSRF token and adds it as a request attribute and as a cookie (AngularJS). * Authorizer which creates a new CSRF token and adds it as a request attribute and as a cookie (AngularJS).
* *
Expand All @@ -22,7 +24,7 @@ public CsrfTokenGeneratorAuthorizer(final CsrfTokenGenerator csrfTokenGenerator)
} }


@Override @Override
public boolean isAuthorized(final WebContext context, final UserProfile profile) { public boolean isAuthorized(final WebContext context, final List<UserProfile> profiles) {
CommonHelper.assertNotNull("csrfTokenGenerator", csrfTokenGenerator); CommonHelper.assertNotNull("csrfTokenGenerator", csrfTokenGenerator);
final String token = csrfTokenGenerator.get(context); final String token = csrfTokenGenerator.get(context);
context.setRequestAttribute(Pac4jConstants.CSRF_TOKEN, token); context.setRequestAttribute(Pac4jConstants.CSRF_TOKEN, token);
Expand Down
Expand Up @@ -15,7 +15,7 @@
*/ */
public interface AuthorizationChecker { public interface AuthorizationChecker {


boolean isAuthorized(WebContext context, UserProfile profile, String authorizerNames, Map<String, Authorizer> authorizersMap); boolean isAuthorized(WebContext context, List<UserProfile> profiles, String authorizerNames, Map<String, Authorizer> authorizersMap);


boolean isAuthorized(WebContext context, UserProfile profile, List<Authorizer> authorizers); boolean isAuthorized(WebContext context, List<UserProfile> profiles, List<Authorizer> authorizers);
} }
Expand Up @@ -31,7 +31,7 @@ public class DefaultAuthorizationChecker implements AuthorizationChecker {
final static CsrfTokenGeneratorAuthorizer CSRF_TOKEN_GENERATOR_AUTHORIZER = new CsrfTokenGeneratorAuthorizer(new DefaultCsrfTokenGenerator()); final static CsrfTokenGeneratorAuthorizer CSRF_TOKEN_GENERATOR_AUTHORIZER = new CsrfTokenGeneratorAuthorizer(new DefaultCsrfTokenGenerator());


@Override @Override
public boolean isAuthorized(final WebContext context, final UserProfile profile, final String authorizerNames, final Map<String, Authorizer> authorizersMap) { public boolean isAuthorized(final WebContext context, final List<UserProfile> profiles, final String authorizerNames, final Map<String, Authorizer> authorizersMap) {
final List<Authorizer> authorizers = new ArrayList<>(); final List<Authorizer> authorizers = new ArrayList<>();
// if we have an authorizer name (which may be a list of authorizer names) // if we have an authorizer name (which may be a list of authorizer names)
if (CommonHelper.isNotBlank(authorizerNames)) { if (CommonHelper.isNotBlank(authorizerNames)) {
Expand Down Expand Up @@ -78,17 +78,17 @@ public boolean isAuthorized(final WebContext context, final UserProfile profile,
} }
} }
} }
return isAuthorized(context, profile, authorizers); return isAuthorized(context, profiles, authorizers);
} }


@Override @Override
public boolean isAuthorized(final WebContext context, final UserProfile profile, final List<Authorizer> authorizers) { public boolean isAuthorized(final WebContext context, final List<UserProfile> profiles, final List<Authorizer> authorizers) {
// authorizations check comes after authentication and profile must not be null // authorizations check comes after authentication and profile must not be null nor empty
CommonHelper.assertNotNull("profile", profile); CommonHelper.assertTrue(profiles != null && profiles.size() > 0, "profiles must not be null or empty");
if (authorizers != null && !authorizers.isEmpty()) { if (authorizers != null && !authorizers.isEmpty()) {
// check authorizations using authorizers: all must be satisfied // check authorizations using authorizers: all must be satisfied
for (Authorizer authorizer : authorizers) { for (Authorizer authorizer : authorizers) {
if (!authorizer.isAuthorized(context, profile)) { if (!authorizer.isAuthorized(context, profiles)) {
return false; return false;
} }
} }
Expand Down
Expand Up @@ -60,7 +60,7 @@ private LinkedHashMap<String, UserProfile> retrieveAll(final boolean readFromSes
if (objSession != null && objSession instanceof LinkedHashMap) { if (objSession != null && objSession instanceof LinkedHashMap) {
profiles = (LinkedHashMap<String, UserProfile>) objSession; profiles = (LinkedHashMap<String, UserProfile>) objSession;
} }
if (profiles == null && readFromSession) { if ((profiles == null || profiles.size() == 0) && readFromSession) {
final Object objRequest = this.context.getSessionAttribute(Pac4jConstants.USER_PROFILES); final Object objRequest = this.context.getSessionAttribute(Pac4jConstants.USER_PROFILES);
if (objRequest != null && objRequest instanceof LinkedHashMap) { if (objRequest != null && objRequest instanceof LinkedHashMap) {
profiles = (LinkedHashMap<String, UserProfile>) objRequest; profiles = (LinkedHashMap<String, UserProfile>) objRequest;
Expand All @@ -86,16 +86,19 @@ public void remove(final boolean removeFromSession) {
} }


/** /**
* Save the given user profile (replace the current one if multi profile is not supported, add it otherwise). * Save the given user profile (replace the current one if multi profiles are not supported, add it otherwise).
* *
* @param saveInSession if the user profile must be saved in session * @param saveInSession if the user profile must be saved in session
* @param profile a given user profile * @param profile a given user profile
* @param multiProfile whether multi profile is supported * @param multiProfile whether multiple profiles are supported
*/ */
public void save(final boolean saveInSession, final UserProfile profile, final boolean multiProfile) { public void save(final boolean saveInSession, final UserProfile profile, final boolean multiProfile) {
final LinkedHashMap<String, UserProfile> profiles; final LinkedHashMap<String, UserProfile> profiles;


final String clientName = profile.getClientName(); String clientName = profile.getClientName();
if (clientName == null) {
clientName = "DEFAULT";
}
if (multiProfile) { if (multiProfile) {
profiles = retrieveAll(saveInSession); profiles = retrieveAll(saveInSession);
profiles.remove(clientName); profiles.remove(clientName);
Expand Down
@@ -1,8 +1,13 @@
package org.pac4j.core.authorization.authorizer; package org.pac4j.core.authorization.authorizer;


import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.pac4j.core.context.MockWebContext; import org.pac4j.core.context.MockWebContext;
import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.UserProfile;

import java.util.ArrayList;
import java.util.List;


import static org.junit.Assert.*; import static org.junit.Assert.*;


Expand All @@ -16,15 +21,23 @@
*/ */
public final class CheckHttpMethodAuthorizerTests { public final class CheckHttpMethodAuthorizerTests {


private List<UserProfile> profiles;

@Before
public void setUp() {
profiles = new ArrayList<>();
profiles.add(new CommonProfile());
}

@Test @Test
public void testGoodHttpMethod() { public void testGoodHttpMethod() {
final CheckHttpMethodAuthorizer authorizer = new CheckHttpMethodAuthorizer(HTTP_METHOD.GET, HTTP_METHOD.POST); final CheckHttpMethodAuthorizer authorizer = new CheckHttpMethodAuthorizer(HTTP_METHOD.GET, HTTP_METHOD.POST);
assertTrue(authorizer.isAuthorized(MockWebContext.create().setRequestMethod("GET"), new CommonProfile())); assertTrue(authorizer.isAuthorized(MockWebContext.create().setRequestMethod("GET"), profiles));
} }


@Test @Test
public void testBadHttpMethod() { public void testBadHttpMethod() {
final CheckHttpMethodAuthorizer authorizer = new CheckHttpMethodAuthorizer(HTTP_METHOD.PUT); final CheckHttpMethodAuthorizer authorizer = new CheckHttpMethodAuthorizer(HTTP_METHOD.PUT);
assertFalse(authorizer.isAuthorized(MockWebContext.create().setRequestMethod("DELETE"), new CommonProfile())); assertFalse(authorizer.isAuthorized(MockWebContext.create().setRequestMethod("DELETE"), profiles));
} }
} }
Expand Up @@ -2,6 +2,10 @@


import org.junit.Test; import org.junit.Test;
import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.UserProfile;

import java.util.ArrayList;
import java.util.List;


import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
Expand All @@ -22,12 +26,16 @@ class FakeProfile2 extends CommonProfile {
@Test @Test
public void testGoodProfile() { public void testGoodProfile() {
final CheckProfileTypeAuthorizer authorizer = new CheckProfileTypeAuthorizer(FakeProfile1.class, FakeProfile2.class); final CheckProfileTypeAuthorizer authorizer = new CheckProfileTypeAuthorizer(FakeProfile1.class, FakeProfile2.class);
assertTrue(authorizer.isAuthorized(null, new FakeProfile1())); final List<UserProfile> profiles = new ArrayList<>();
profiles.add(new FakeProfile1());
assertTrue(authorizer.isAuthorized(null, profiles));
} }


@Test @Test
public void testBadProfileType() { public void testBadProfileType() {
final CheckProfileTypeAuthorizer authorizer = new CheckProfileTypeAuthorizer(FakeProfile1.class); final CheckProfileTypeAuthorizer authorizer = new CheckProfileTypeAuthorizer(FakeProfile1.class);
assertFalse(authorizer.isAuthorized(null, new FakeProfile2())); final List<UserProfile> profiles = new ArrayList<>();
profiles.add(new FakeProfile2());
assertFalse(authorizer.isAuthorized(null, profiles));
} }
} }

0 comments on commit 677284b

Please sign in to comment.