Radek Rodak [
http://community.jboss.org/people/rodakr] created the discussion
"Re: Security propagation from remote EJB clients to AS7"
To view the discussion, visit:
http://community.jboss.org/message/644551#644551
--------------------------------------------------------------
Hi
1)
Can you provide client sample code using SASL Security ( for now PLAIN example would be
enought ).
( or just add this example to
https://docs.jboss.org/author/display/AS71/Developer+Guide#DeveloperGuide...
https://docs.jboss.org/author/display/AS71/Developer+Guide#DeveloperGuide...
)
2)
I looked in source code of org.jboss.sasl.JBossSaslProvider.java (
jboss-sasl-1.0.0.Beta9.jar )
Ony SASL MECH I see here are:
"ANONYMOUS"
"PLAIN",
"DIGEST-MD5",
"JBOSS-LOCAL-USER"
Could you also add "GSSAPI" ( here how to from Darran Lofthouse
http://community.jboss.org/docs/DOC-17302 http://community.jboss.org/wiki/SASLAndKerberos
)
Basically I would like to do this but with AS7.1:
http://community.jboss.org/docs/DOC-16137
http://community.jboss.org/wiki/EJB3AuthenticationWithSPNEGO
I tried to call remote ejb after sucessfull JAAS Login, but JAAS Login Context seams to
not get propagatet to Server over Jboss Remote...
Here how I tried ( the same Code but calling Web URL Secured with SPNEGO works, so KRB5
Java Setup is ok) :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedExceptionAction;
import java.security.Security;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Set;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.security.auth.Subject;
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.TextInputCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import test.ejb3.TestServiceItf;
public class TestServiceClient {
static String JAAS_CONFIG_ENTRY = "com.sun.security.jgss.krb5.initiate";
static BufferedReader br = new BufferedReader( new InputStreamReader (System.in));
public static void main(String[] args) throws Exception {
LoginContext lc = null;
try {
System.out.println("\n >> Enter Win user Name : ");
//String callbackUser = br.readLine ();
String callbackUser = "rrad";
System.out.println("\n >> Enter Win User AD password : ");
//String callbackPwd = br.readLine ();
String callbackPwd ="radoslaw13";
// jaas collback might be needed for ticket refresh...
lc = new LoginContext(JAAS_CONFIG_ENTRY,new
NamePasswordCallbackHandler2(callbackUser,callbackPwd ));
lc.login();
//and get a subject
Subject mySubject = lc.getSubject();
System.out.println(" *********??????????********>>>> subject:
"+mySubject);
Set<Principal> sp = mySubject.getPrincipals();
if ( sp == null ) System.out.println(" 0 principals ");
else {
System.out.println(+sp.size()+" principals");
for ( Principal p : sp ) {
System.out.println("principal name :"+p.getName());
}
}
// in case if not passed to java as property..
System.setProperty("javax.security.auth.useSubjectCredsOnly",
"false");
System.setProperty( "sun.security.krb5.debug", "true");
PrivilegedExceptionAction<String> action = new GetAction( null, null
);
//jaas call the service
String aRet = (String)mySubject.doAs(mySubject, action);
// successfuly called, read returned values
System.out.println("successfully caled protected Method : "+aRet);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
/**
* dummy readLine Helper
* @return
*/
public static String readLine(String message)
{
String s = null;
System.out.println(message);
try {
InputStreamReader converter = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(converter);
s = in.readLine();
} catch (Exception e) {
System.out.println("Error! Exception: "+e);
} finally {
System.out.println("");
}
return s;
}
}
class GetAction implements PrivilegedExceptionAction<String> {
private String toke;
private String user;
private String testEjbItf="test.ejb3.TestServiceItf";
// context.lookup("ejb:" + appName + "/" + moduleName +
"/" + distinctName + "/" + beanName + "!" + viewClassName);
private String
testEjbJndi="ejb:/sl-securityTestEjb3//TestServiceSLEJB3Bean!test.ejb3.TestServiceItf";
public GetAction(String user , String token) {
this.user = user;
this.toke=token;
}
static {
try {
Sasl.createSaslClient(new String[]{"PLAIN"}, null,
"remoting", "ux2084", Collections.EMPTY_MAP, new
NamePasswordCallbackHandler2("rrad","radoslaw13" ) );
} catch (SaslException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// make shure
public String run() throws Exception {
//Sasl.createSaslClient(new String[]{"GSSAPI"}, null,
"remoting", "ux2084", Collections.EMPTY_MAP, new
NamePasswordCallbackHandler2("xxx","yyy" ) );
//Sasl.createSaslClient(new String[]{"PLAIN"}, null,
"remoting", "ux2084", Collections.EMPTY_MAP, new
NamePasswordCallbackHandler2("xxx","yyy" ) );
javax.security.auth.Subject currentSubject =
javax.security.auth.Subject.getSubject( AccessController.getContext());
if ( currentSubject == null ) System.out.println(" our Action runs as
Subject: null ");
else System.out.println(" our Action runs as Subject:
"+currentSubject.toString());
Context ctx = getInitialContext();
System.out.println("Initial Context created");
System.out.println("lookup"+testEjbJndi+"
@RolesAllowed({\"BackofficeRole\"})");
Class itfClass =
Thread.currentThread().getContextClassLoader().loadClass(testEjbItf);
TestServiceItf testService = (TestServiceItf) ctx.lookup(testEjbJndi);
System.out.println("lookup testEjbJndi successful");
System.out.println(" call unsecured Method permittAllMethod()");
Subject asu = testService.permittAllMethod(" calling unsecured");
System.out.println(" successfully called, received Subject: "+asu);
System.out.println(" call secured Method with role
"+testService.BACKOFFICE_ROLE);
asu = testService.pwvAuthenticatorSecuredMethod(" calling secured");
System.out.println(" successfully called, received Subject: "+asu);
return "Test ok";
}
private static Context getInitialContext() throws NamingException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES,
"org.jboss.ejb.client.naming");
jndiProperties.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
final Context context = new InitialContext(jndiProperties);
return context;
}
}
class NamePasswordCallbackHandler2 implements CallbackHandler
{
/**
* The username to be provided when prompted.
*/
private String username;
/**
* The password to be provided when prompted.
*/
private String password;
private String url;
/**
* Create a new NamePasswordCallbackHandler (required Cams default
* constructor that is dynamically called by the authentication
* server).
* @param anURL
* @param callbackPwd
* @param callbackUser
*/
public NamePasswordCallbackHandler2(String callbackUser, String callbackPwd)
{
this.username = callbackUser;
this.password = callbackPwd;
}
/**
* Set the username.
*
* @param username the username to be provided to a NameCallback.
*/
public void setUsername(String username)
{
if (username == null)
{
this.username = "";
return;
}
this.username = username;
}
/**
* Set the password.
*
* @param password the password to be provided to a PasswordCallback.
*/
public void setPassword(String password)
{
if (password == null)
{
this.password = "";
return;
}
this.password = password;
}
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException
{
for(int i = 0; i < callbacks.length; i++)
{
if(callbacks[i] instanceof TextOutputCallback)
{
// Display the message according to the specified type
TextOutputCallback toc = (TextOutputCallback)callbacks[i];
switch(toc.getMessageType())
{
case TextOutputCallback.INFORMATION:
log(toc.getMessage());
break;
case TextOutputCallback.ERROR:
log("ERROR: " + toc.getMessage());
break;
case TextOutputCallback.WARNING:
log("WARNING: " + toc.getMessage());
break;
default:
throw new IOException("Unsupported message type:
"+toc.getMessageType());
}
}
else if(callbacks[i] instanceof NameCallback)
{
// If username not supplied on cmd line, prompt the user for the username.
NameCallback nc = (NameCallback)callbacks[i];
if (username == null || username.isEmpty()) {
System.err.print(nc.getPrompt());
System.err.flush();
nc.setName((new BufferedReader(new InputStreamReader(System.in))).readLine());
}
else {
log("username: "+username);
nc.setName(username);
}
}
else if(callbacks[i] instanceof PasswordCallback)
{
PasswordCallback pc = (PasswordCallback)callbacks[i];
// If password not supplied on cmd line, prompt the user for the password.
if (password == null || password.isEmpty()) {
System.err.print(pc.getPrompt());
System.err.flush();
// Note: JAAS specifies that the password is a char[] rather than a String
String tmpPassword = (new BufferedReader(new
InputStreamReader(System.in))).readLine();
int passLen = tmpPassword.length();
char[] passwordArray = new char[passLen];
for(int passIdx = 0; passIdx < passLen; passIdx++)
passwordArray[passIdx] = tmpPassword.charAt(passIdx);
pc.setPassword(passwordArray);
}
else {
String tPass = new String();
for(int p = 0; p < password.length(); p++)
tPass += "*";
log("password: "+tPass);
pc.setPassword(password.toCharArray());
}
}
else if(callbacks[i] instanceof TextInputCallback)
{
// Prompt the user for the username
TextInputCallback callback = (TextInputCallback)callbacks[i];
System.err.print(callback.getPrompt());
System.err.flush();
callback.setText((new BufferedReader(new
InputStreamReader(System.in))).readLine());
}
else
{
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized
Callback");
}
}
}
private void log(String str) { System.out.println(str); }
Happy New Year
Radek Rodak
--------------------------------------------------------------
Reply to this message by going to Community
[
http://community.jboss.org/message/644551#644551]
Start a new discussion in JBoss AS 7 Development at Community
[
http://community.jboss.org/choose-container!input.jspa?contentType=1&...]