From d88017518c1465349d3695af4580cd6a563e5bd0 Mon Sep 17 00:00:00 2001 From: Martin Weiler Date: Wed, 11 Jan 2017 14:50:36 +0100 Subject: [PATCH] RHBPMS-473: Set TCCL to workaround login failures with JSM enabled --- .../security/JAASAuthenticationService.java | 81 +++++++++++++------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/JAASAuthenticationService.java b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/JAASAuthenticationService.java index 80dede01aa..69eb210b01 100644 --- a/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/JAASAuthenticationService.java +++ b/uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/JAASAuthenticationService.java @@ -16,6 +16,20 @@ package org.uberfire.backend.server.security; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.List; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Alternative; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.api.identity.UserImpl; @@ -24,16 +38,6 @@ import org.uberfire.backend.server.security.adapter.GroupAdapterAuthorizationSource; import org.uberfire.commons.validation.PortablePreconditions; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Alternative; -import javax.security.auth.callback.*; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.List; - /** * Implements stateful, thread-local authentication of a user via the JAAS API ( * {@code javax.security.auth.login.LoginContext}). @@ -42,7 +46,8 @@ * authenticated user. This association is only undone upon a call to {@link #logout()}. This is appropriate for use * with the Git SSH daemon, but would cause serious security issues if used for authenticating HTTP requests. */ -@ApplicationScoped @Alternative +@ApplicationScoped +@Alternative public class JAASAuthenticationService extends GroupAdapterAuthorizationSource implements AuthenticationService { public static final String DEFAULT_DOMAIN = "ApplicationRealm"; @@ -59,21 +64,49 @@ public JAASAuthenticationService(String domain) { } @Override - public User login( String username, String password ) { - try { - final LoginContext loginContext = createLoginContext( username, password ); - loginContext.login(); - List principals = loadEntitiesFromSubjectAndAdapters( username, loginContext.getSubject(), new String[] { rolePrincipleName } ); - Collection roles = getRoles( principals ); - Collection groups = getGroups( principals ); - UserImpl user = new UserImpl( username, roles, groups ); - userOnThisThread.set( user ); - return user; - } catch ( final LoginException ex ) { - throw new FailedAuthenticationException(); + public User login( final String username, + final String password ) { + final SecurityManager jsm = System.getSecurityManager(); + + if ( jsm != null ) { + final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + final ClassLoader cl = this.getClass().getClassLoader(); + try { + // RHBPMS-473 - TCCL used in javax.security.auth.login.LoginContext + // is not the application CL if JSM is enabled. + // Setting TCCL to application CL as workaround + Thread.currentThread().setContextClassLoader( cl ); + + return executeLogin( username, password ); + } catch ( final LoginException ex ) { + throw new FailedAuthenticationException(); + } finally { + // RHBPMS-473 - Restore original TCCL + if ( tccl != null ) { + Thread.currentThread().setContextClassLoader( tccl ); + } + } + } else { + try { + return executeLogin( username, password ); + } catch ( final LoginException ex ) { + throw new FailedAuthenticationException(); + } } } + private User executeLogin( final String username, + final String password ) throws LoginException { + final LoginContext loginContext = createLoginContext( username, password ); + loginContext.login(); + List principals = loadEntitiesFromSubjectAndAdapters( username, loginContext.getSubject(), new String[]{ rolePrincipleName } ); + Collection roles = getRoles( principals ); + Collection groups = getGroups( principals ); + UserImpl user = new UserImpl( username, roles, groups ); + userOnThisThread.set( user ); + return user; + } + @Override public void logout() { userOnThisThread.remove(); @@ -127,4 +160,4 @@ public void handle( final Callback[] callbacks ) throws IOException, Unsupported } } -} \ No newline at end of file +}