星期三, 二月 25, 2004

Jboss Base JAAS 实现LDAP 验证(最终)

1.配置config/login-config.xml加入:
<application-policy name="AdminRealm">
<authentication>
<login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required">
<module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option>
<module-option name="java.naming.provider.url">ldap://localhost:389/</module-option>
<module-option name="java.naming.security.authentication">simple</module-option>
<module-option name="principalDNPrefix">cn=</module-option>
<module-option name="principalDNSuffix">,dc=sunose,dc=com</module-option>
<module-option name="rolesCtxDN">ou=Roles,o=sunose.com</module-option>
<module-option name="roleAttributeID">description</module-option>
<module-option name="uidAttributeID">sn</module-option>
<module-option name="matchOnUserDN">false</module-option>
</login-module>
</authentication>
</application-policy>

2.配置使用的web Module web.xml 加入:
<security-constraint>
<display-name>
<![CDATA[Constraints of the Administration Console's Security Environment]]>
</display-name>
<web-resource-collection>
<web-resource-name>Protected Web Resources</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>Administrator</role-name>
</auth-constraint>
<user-data-constraint>
<description>no description</description>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/index.jsp</form-login-page>
<form-error-page>/error.html</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>Administrator</role-name>
</security-role>
3.修改jboss-web.xml加入:
<jboss-web>
<security-domain>AdminRealm</security-domain><!--注意这里的domain同步骤1中login-config.xml配置的application-policy保持一致-->
<context-root>payroll</context-root>
</jboss-web>

4.开发CallbackHandler Class,如下(基于Servlet,如果是其他方式比如client写法有不同)
static class AppCallbackHandler implements CallbackHandler {
private String pusername;
private char[] ppassword;

public AppCallbackHandler(String username, char[] password)
{
this.pusername = username;
this.ppassword = password;
}

public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException
{

for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {

System.out.println("handle " + i + ": callbacks["+i+"] instanceof NameCallback");

NameCallback nc = (NameCallback)callbacks[i];

System.out.println("setting username to Carrier");
nc.setName(pusername);
}
else if (callbacks[i] instanceof PasswordCallback)
{
System.out.println("handle " + i + ": callbacks["+i+"] instanceof PasswordCallback");
PasswordCallback pc = (PasswordCallback)callbacks[i];
System.out.println("setting password to Carrier");
pc.setPassword(ppassword);
}
else {
System.out.println("handle: unrecognized callback " + callbacks[i].getClass().getName());
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}

5.在Servlet中使用LoginContext来实现authentication.(认证).
....在合适位置加入下列代码.

LoginContext lc = null;
try {
lc = new LoginContext("AdminRealm", new AppCallbackHandler(username,password.toCharArray()));
System.out.println("Ready for Login");
lc.login();
}catch (LoginException le)
{
System.err.println("Cannot create LoginContext. " + le.getMessage());
} catch (SecurityException se) {
System.err.println("Cannot create LoginContext. " + se.getMessage());
}

6.发布打包,既可.