Wednesday, April 27, 2005


JavaTM Authentication and Authorization Service (JAAS)
- Sun Offical JAAS Site

- JavaDoc of sun JAAS Package here
- JAAS Tutorial here

After two data investingate.. I found that JAAS is extremely non-user friendly...
Anyway, Here are soem tips and tricks.
First, the NTLoginModule moudle provided by Sun can't allow user to input the domain anme, username and password..... The API takes these information from the underlayer OS and Subject with this input,authenticated and passed on Successfully!!!!!!!!!! If a user can login it's computer he can denfinly pass this test.... So, what is of use of this module...??
I guess it is used for Singel-Sign-On if a user can login their windows their can enjoy the SSO service. What the programers can do is to specify the right principals in the policy and manage the right of differrent group of users!!

If you just want to use the Authentication service from the Domain Controller there still some solutions:

1) Using the NTActiveLoginModule from IBM

Config file setting:
 MyLoginModules { REQUIRED;
This LoginModule - permits using our Callbackhandler. We can then setUsername and setPassword and get it authenticated.

IMPORTANT uide.win32.html#wq10

Some forum link that would help: ;forum=178&cat=10&message=12026825#12026825

To make use of this functioanlity, you should have IBM's JDK. Particularly the jaas_activelm.jar, jaas.jar and jaasal.dll . I had Websphere. Hence I got this. I am not sure how to get it otherwise.

2)Using the JAAS Module from

- Tagish Documentation

If you think using IBM JDK is a bit clumbersome or troublesome, you can just download a module from Tagish, However, the update is on 2003/02/17, the library is a bit old but I can still runnning it on my JDK1.5 and MS Windows XP(SR2). The source code is included is downloadable, if everyone can compile it on their compiler!!!

Here is my simple code using Tahish:

Run Command:

java -cp classes\Data\eclipse\workspace\NTLoginSystem\NT.config -Djava.library.path=C:\Data\eclipse\workspace\NTLoginSystem
Config file Setting:
com.tagish.auth.win32.NTSystemLogin required returnNames=true returnSIDs=false defaultDomain="domain";

Some Test Code:
Main class:
public class Main {
  public static void main(String[] args) {
      LoginContext lc;
      Subject subject = null;
      try {
          lc = new LoginContext( "NT", new MyCallbackHandler() );
          subject = lc.getSubject();
    System.out.println("Login Success");
      } catch ( LoginException le ) {
          System.err.println( "Cannot create LoginContext. "
                  + le.getMessage() );
      } catch ( SecurityException se ) {
          System.err.println( "Cannot create LoginContext. "
                  + se.getMessage() );

      System.out.println("Subject: " + subject);

MyCallbackHandler class:
class MyCallbackHandler implements CallbackHandler {
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {

for (int i = 0; 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:
case TextOutputCallback.ERROR:
System.out.println("ERROR: " + toc.getMessage());
case TextOutputCallback.WARNING:
System.out.println("WARNING: " + toc.getMessage());
throw new IOException("Unsupported message type: " +

} else if (callbacks[i] instanceof NameCallback) {

// prompt the user for a username
NameCallback nc = (NameCallback)callbacks[i];

nc.setName((new BufferedReader
(new InputStreamReader(;

} else if (callbacks[i] instanceof PasswordCallback) {

// prompt the user for sensitive information
PasswordCallback pc = (PasswordCallback)callbacks[i];

} else {
throw new UnsupportedCallbackException
(callbacks[i], "Unrecognized Callback");

// Reads user password from given input stream.
private char[] readPassword(InputStream in) throws IOException {

char[] lineBuffer;
char[] buf;
int i;

buf = lineBuffer = new char[128];

int room = buf.length;
int offset = 0;
int c;

loop: while (true) {
switch (c = {
case -1:
case '\n':
break loop;

case '\r':
int c2 =;
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
} else
break loop;

if (--room <>
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
buf[offset++] = (char) c;

if (offset == 0) {
return null;

char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');

return ret;

Login Success
Subject: 主題:
Principal: NTUserPrincipal: fcmmok [USER]
Principal: NTDomainPrincipal: HPFDCC3 [DOMAIN]
Principal: NTGroupPrincipal: Domain Users [GROUP]
Principal: NTGroupPrincipal: Everyone [GROUP]
Principal: NTGroupPrincipal: Users [GROUP]
Principal: NTGroupPrincipal: Domain Admins [GROUP]
Principal: NTGroupPrincipal: NETWORK [GROUP]
Principal: NTGroupPrincipal: Authenticated Users [GROUP]

No comments: