HHH-11805 Fix JACC cannot be enabled

This commit is contained in:
Guillermo González de Agüero 2017-06-11 13:45:01 +02:00 committed by Vlad Mihalcea
parent f2c83c9653
commit 20d17ec0f2
3 changed files with 185 additions and 9 deletions

View File

@ -72,6 +72,7 @@ dependencies {
testCompile( project(':hibernate-testing') )
testCompile( libraries.shrinkwrap_api )
testCompile( libraries.shrinkwrap )
testCompile( libraries.jacc )
testCompile( libraries.validation )
testCompile( libraries.jandex )
testCompile( libraries.classmate )

View File

@ -87,6 +87,7 @@ import org.jboss.jandex.Index;
import static org.hibernate.cfg.AvailableSettings.DATASOURCE;
import static org.hibernate.cfg.AvailableSettings.DRIVER;
import static org.hibernate.cfg.AvailableSettings.JACC_CONTEXT_ID;
import static org.hibernate.cfg.AvailableSettings.JACC_ENABLED;
import static org.hibernate.cfg.AvailableSettings.JACC_PREFIX;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_DRIVER;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_PASSWORD;
@ -483,15 +484,17 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
final String valueString = (String) entry.getValue();
if ( keyString.startsWith( JACC_PREFIX ) ) {
if ( jaccContextId == null ) {
LOG.debug(
"Found JACC permission grant [%s] in properties, but no JACC context id was specified; ignoring"
);
}
else {
mergedSettings.getJaccPermissions( jaccContextId ).addPermissionDeclaration(
parseJaccConfigEntry( keyString, valueString )
);
if( !JACC_CONTEXT_ID.equals( keyString ) && !JACC_ENABLED.equals( keyString )) {
if ( jaccContextId == null ) {
LOG.debug(
"Found JACC permission grant [%s] in properties, but no JACC context id was specified; ignoring"
);
}
else {
mergedSettings.getJaccPermissions( jaccContextId ).addPermissionDeclaration(
parseJaccConfigEntry( keyString, valueString )
);
}
}
}
else if ( keyString.startsWith( CLASS_CACHE_PREFIX ) ) {

View File

@ -0,0 +1,172 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.secure;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.security.Provider;
import java.util.Collections;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.security.auth.Subject;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.security.jacc.PolicyContextHandler;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Vlad Mihalcea
*/
@TestForIssue( jiraKey = "HHH-11805" )
public class JaccIntegratorTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Person.class,
};
}
@Override
protected void addConfigOptions(Map options) {
options.put( AvailableSettings.JACC_ENABLED, Boolean.TRUE.toString() );
options.put( AvailableSettings.JACC_CONTEXT_ID, "JACC_CONTEXT_ID" );
options.put( "hibernate.jacc.allowed.org.hibernate.secure.Customer", "insert" );
}
@Override
protected void afterEntityManagerFactoryBuilt() {
PolicyContextHandler policyContextHandler = new PolicyContextHandler() {
@Override
public Object getContext(String key, Object data) throws PolicyContextException {
Subject subject = new Subject( true, Collections.singleton(new java.security.Principal() {
@Override
public String getName() {
return "org.hibernate.secure.JaccIntegratorTest$Person";
}
@Override
public boolean implies(Subject subject) {
return true;
}
}), Collections.emptySet(), Collections.emptySet());
return subject;
}
@Override
public String[] getKeys() throws PolicyContextException {
return new String[0];
}
@Override
public boolean supports(String key) throws PolicyContextException {
return true;
}
};
try {
PolicyContext.registerHandler( "javax.security.auth.Subject.container", policyContextHandler, true);
}
catch (PolicyContextException e) {
fail(e.getMessage());
}
}
protected void setPolicy(boolean allow) {
Policy.setPolicy( new Policy() {
@Override
public Provider getProvider() {
return super.getProvider();
}
@Override
public String getType() {
return super.getType();
}
@Override
public Parameters getParameters() {
return super.getParameters();
}
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
return super.getPermissions( codesource );
}
@Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
return super.getPermissions( domain );
}
@Override
public boolean implies(ProtectionDomain domain, Permission permission) {
return allow;
}
@Override
public void refresh() {
super.refresh();
}
} );
}
@Test
public void testAllow() {
setPolicy( true );
doInJPA( this::entityManagerFactory, entityManager -> {
Person person = new Person();
person.id = 1L;
person.name = "John Doe";
entityManager.persist( person );
} );
}
@Test
public void testDisallow() {
setPolicy( false );
try {
doInJPA( this::entityManagerFactory, entityManager -> {
Person person = new Person();
person.id = 1L;
person.name = "John Doe";
entityManager.persist( person );
} );
fail("Should have thrown SecurityException");
}
catch (Exception e) {
assertTrue( e.getCause() instanceof SecurityException );
}
}
@Entity
public static class Person {
@Id
private Long id;
private String name;
}
}