Skip to content
This repository has been archived by the owner on Feb 9, 2021. It is now read-only.

Commit

Permalink
RHBPMS-473: Set TCCL to workaround login failures with JSM enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Weiler authored and porcelli committed Jan 23, 2017
1 parent e7bb624 commit d880175
Showing 1 changed file with 57 additions and 24 deletions.
Expand Up @@ -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;
Expand All @@ -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}).
Expand All @@ -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";
Expand All @@ -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<String> principals = loadEntitiesFromSubjectAndAdapters( username, loginContext.getSubject(), new String[] { rolePrincipleName } );
Collection<Role> roles = getRoles( principals );
Collection<org.jboss.errai.security.shared.api.Group> 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<String> principals = loadEntitiesFromSubjectAndAdapters( username, loginContext.getSubject(), new String[]{ rolePrincipleName } );
Collection<Role> roles = getRoles( principals );
Collection<org.jboss.errai.security.shared.api.Group> groups = getGroups( principals );
UserImpl user = new UserImpl( username, roles, groups );
userOnThisThread.set( user );
return user;
}

@Override
public void logout() {
userOnThisThread.remove();
Expand Down Expand Up @@ -127,4 +160,4 @@ public void handle( final Callback[] callbacks ) throws IOException, Unsupported
}
}

}
}

0 comments on commit d880175

Please sign in to comment.