# Kriege JAAS einfach nicht zum Laufen



## peez (3. Nov 2010)

Ich bin seit einiger Zeit dabei, einen JAAS Login mit EJB3 auf jboss 6 hinzubekommen. Ich glaube am Server habe ich jetzt alles soweit richtig, glaube am Login vom Client hapert es noch. Gibt leider so wenig im Netz darüber zu lesen... Auch mein extra angeschafftes EJB3.0 Buch macht diesbezüglich nur ganz wage Aussagen..

Also was ich habe:

Habe die Datei jboss/server/default/conf/login-config.xml so angepasst:
[XML]
<policy>
<!-- ...... -->
   <application-policy name="DPMAM">
		<authentication>
			<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule"
				flag="required">
				<module-option name="unauthenticatedIdentity">guest</module-option>
				<module-option name="dsJndiName">java:/dpmam_ds</module-option>
				<module-option name="principalsQuery">SELECT USER_PasswordMD5 FROM USERs
					WHERE
					USER_Name=?</module-option>
				<module-option name="rolesQuery">SELECT USGR_Name, 'Group' FROM USerGRoups
					INNER JOIN USER_USGR_Zugehoerigkeit ON
					USerGRoups.USGR_ID=USER_USGR_Zugehoerigkeit.USGR_ID
					INNER JOIN USERs ON USER_USGR_Zugehoerigkeit.USER_ID=USERs.USER_ID
					WHERE USERs.USER_Name=?</module-option>
			</login-module>
		</authentication>
	</application-policy>

</policy>
[/XML]
Stimmen die Spalten beim Roles-Query? (Der Join funktioniert so)

Dann habe ich in der Bean folgendes:

```
@Stateless(name = "BalancerBean")
@SecurityDomain("DPMAM")
public class BalancerBean implements BalancerBeanRemote {

	private static Logger log = LoggerFactory.getLogger( BalancerBean.class );
        

        //......

	@Override
	public String ping() {
		return "pong";
	}

	@Override
	@RolesAllowed( { "Administrator" })
	public String restrictedPing() {
		return "restrictedPong";
	}
}
```

In meinem Client:

```
//...
public static void main(String[] args) {
Properties locatorProperties = new Properties();
locatorProperties.setProperty( Context.SECURITY_PRINCIPAL, "admin"); //<-- Diese beiden Zeilen habe ich aus meinem schlauen Buch
locatorProperties.setProperty( Context.SECURITY_CREDENTIALS, "21232f297a57a5a743894a0e4a801fc3");
locatorProperties.put( "java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
locatorProperties.put( "java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );
locatorProperties.put( "java.naming.provider.url", "localhost:1099" );

Context initialContext = new InitialContext( locatorProperties);

BalancerBeanRemote bean = (BalancerBeanRemote)initialContext.lookup( BalancerBeanRemote.JNDI_NAME );


System.out.println(bean.ping());
System.out.println(bean.restrictedPing());

}
```

Der Aufruf von ping() funktioniert, bei restrictedPing() gibts ne EJBAccessException (Caller unauthorized).

Was könnte denn noch fehlen?


----------



## FArt (4. Nov 2010)

Ich sehe bei dir keinen LoginContext auf dem Client.

Guckst du hier: JAAS Authentication Tutorial


----------



## peez (4. Nov 2010)

Aha.. Den LoginContext habe ich früher schonmal probiert aber war nicht erfolgreich.. Diesmal siehts etwas besser aus aber laufen tuts trotzdem nicht :-(


Mein Client sieht jetzt so aus:

```
public class Test {

	public static void main( String[] args ) {

		Properties locatorProperties = new Properties();
		// locatorProperties.setProperty( Context.SECURITY_PRINCIPAL, "admin" );
		// locatorProperties.setProperty( Context.SECURITY_CREDENTIALS, "21232f297a57a5a743894a0e4a801fc3" );
		locatorProperties.put( "java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
		locatorProperties.put( "java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );
		locatorProperties.put( "java.naming.provider.url", "localhost:1099" );

		// Statt VM-Argument
		System.setProperty( "java.security.auth.login.config", "bin/META-INF/dpmam_jaas.config" );

		// Würde ich diese System-Properties nicht setzten würde ich eine NoInitialContextException bekommen
		System.setProperty( "java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
		System.setProperty( "java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );
		System.setProperty( "java.naming.provider.url", "localhost:1099" );

		try {
			Context initialContext = new InitialContext( locatorProperties );
			LoginCallbackHandler handler = new LoginCallbackHandler( "admin", "21232f297a57a5a743894a0e4a801fc3" );
			LoginContext lc = new LoginContext( "DPMAM", handler );
			lc.login();

			BalancerBeanRemote bean = (BalancerBeanRemote)initialContext.lookup( BalancerBeanRemote.JNDI_NAME );

			System.out.println( bean.ping() );
			System.out.println( bean.restrictedPing() );
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (LoginException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static class LoginCallbackHandler implements CallbackHandler {

		private String username;

		private String password;

		public LoginCallbackHandler( String username, String password ) {
			this.username = username;
			this.password = password;
		}

		@Override
		public void handle( Callback[] callbacks ) throws IOException, UnsupportedCallbackException {
			for ( Callback callback : callbacks ) {
				if ( callback instanceof NameCallback ) {
					( (NameCallback)callback ).setName( username );
				} else if ( callback instanceof PasswordCallback ) {
					( (PasswordCallback)callback ).setPassword( password.toCharArray() );
				} else {
					throw new UnsupportedCallbackException( callback, "Unsupported Callback" );
				}
			}
		}

	}
}
```

und die Datei dpmam_jaas.config so:

```
DPMAM {
   org.jboss.security.auth.spi.DatabaseServerLoginModule required debug=true;
};
```

Bei lc.login() bekomme ich jetzt diese Exception:

```
javax.security.auth.login.LoginException: java.lang.IllegalStateException: Transaction Manager is null
	at org.jboss.security.auth.spi.DatabaseServerLoginModule.getUsersPassword(DatabaseServerLoginModule.java:158)
	at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:245)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
```

Im Classpath habe ich übrigens keine spezielle Lib...


----------



## FArt (5. Nov 2010)

Bei dir passt was grundsätzliches nicht.
Die JNDI Properties müssen nicht als Systemproperties gesetzt werden UND explizit für den InitialContext. Eines davon muss reichen. Ich empfehle eine Datei jndi.properties im Klassenpfad.
Soweit ich weiß, ist der login auf dem LoginContext kein Remotecall. Da werden nur Credentials in der Client-VM gesetzt, die bei einem Bean Call dann autoamtisch vom ClientLoginModul an das ServerLoginModul übermittelt werden. Somit ist die Exception dort sehr seltsam.

Fange noch mal von vorne an und halte dich an die Doku bei JBoss bzw. an das Tutorial über JAAS.


----------

