我正在尝试使用 spring security 3.1 对 ldap 服务器进行身份验证。
我对 ldap 的了解为零到很少。
在旧代码中,大约有 7 年的历史。我们有一个调用登录对象的 servlet
mypackage.Login login = new mypackage.Login("*******",
"389",
"none",
"cn",
"ou=Employees, ou=**, o=ny, c=US",
"ou=Employees, ou=**, o=ny, c=US",
v);
String[] res = login.authenticate(username, password);
登录代码如下:
package mypackage;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.util.StringTokenizer;
import java.lang.*;
import java.util.regex.*;
import javax.naming.*;
import javax.naming.directory.*;
import mypackage.LoginErrorBean;
import javax.naming.NamingException;
public class Login
{
private static String INITCTX = "com.sun.jndi.ldap.LdapCtxFactory";
private String host;
private String port;
private String encryption;
private String mgrdnattrib;
private String mgrdnpath;
private String searchbase;
private Vector attribs;
private LoginErrorBean myErrors = new LoginErrorBean();
public Login() {}
public Login(String host,String port,String encryption,String mgrdnattrib,String mgrdnpath,String searchbase,Vector attribs)
{
// Parameter settings to connect to desired LDAP service.
// Note: the encryption piece does not seem to work at all
this.host = host;
this.port = port;
this.encryption = encryption;
this.mgrdnattrib = mgrdnattrib;
this.mgrdnpath = mgrdnpath;
this.searchbase = searchbase;
this.attribs = attribs;
}
public String[] authenticate(String username, String password) throws NamingException
{
String[] authenticate;
authenticate = new String [5];
//Set default authentication code to false, f. Authentication is considered valid if value other than 'f' is returned for [0]
authenticate[0] = "f";
try {
String MGR_DN = mgrdnattrib + "=" + username.toUpperCase() + "," + mgrdnpath;
String MGR_PW = password;
String provider = "ldap://" + host + ":" + port;
// Parse atributes
String MY_ATTRS[] = new String[attribs.size()];
for (int i = 0; i < attribs.size(); ++i) {MY_ATTRS[i] = (String)attribs.get(i);}
// Specify the search filter to match for general users
String MY_FILTER ="("+ mgrdnattrib+"=*)";
Hashtable env = new Hashtable();
// Specify which class to use for our JNDI provider
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, provider);
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,MGR_DN);
env.put(Context.SECURITY_CREDENTIALS,MGR_PW);
if ( encryption.toUpperCase().compareTo("SSL") == 0 ) {env.put(Context.SECURITY_PROTOCOL,"ssl");}
// Specify host and port to use for directory service
// Get a reference to a directory context
DirContext ctx = new InitialDirContext(env);
// Specify the scope of the search
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
// Perform the actual search
// We give it a searchbase, a filter and a the constraints
// containing the scope of the search
NamingEnumeration results = ctx.search(searchbase,MY_FILTER, constraints);
Attribute fn = null;
Attribute last = null;
Attributes res = null;
Attribute ou = null;
Attribute tel = null;
Attribute rm = null;
String givenname = "";
String ln = "";
String area = "";
String phone = "";
String room = "";
if (results != null && results.hasMore()) {
SearchResult sr = (SearchResult) results.next();
//Attempt to retrieve the ou
try
{ res = sr.getAttributes();
ou = res.get("ou");
area = ou.toString();
} catch (Exception ex) {ex.printStackTrace();}
finally {}
area.trim();
//Given name
try
{ fn = res.get("givenname");
givenname = fn.toString();
givenname = givenname.replaceAll("givenName:","");
givenname = givenname.trim();
authenticate[1]=givenname;
} catch (Exception ex) {ex.printStackTrace();}
finally {}
//sn
try
{ last = res.get("sn");
ln = last.toString();
ln = ln.replaceAll("sn:","");
ln = ln.trim();
authenticate[2]= ln;
} catch (Exception ex) {ex.printStackTrace();}
finally {}
//Phone
try
{ tel = res.get("telephonenumber");
phone = (tel.toString()==null?"No Phone":tel.toString());
if(phone.length()==0)
{phone="telephoneNumber:None";}
phone = phone.replaceAll("telephoneNumber:","");
phone = phone.trim();
authenticate[3]= phone;
} catch (Exception ex) {ex.printStackTrace();}
finally {}
//Room
try
{ rm = res.get("l");
room = rm.toString();
if(room.length()==0)
{room="l:None";}
room = room.replaceAll("l:","");
room = room.trim();
authenticate[4]= room;
} catch (Exception ex) {ex.printStackTrace();}
finally {}
authenticate [0] = "u";
/**
* This section appears to check again, confirming that the username for login is the same login name found in LDAP.
* It seems like this is repetitive, will maintain for now however. 10/30/06 axk
*/
}
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
authenticate[1] = e.getMessage();
myErrors.addErrorMessage(e.toString());
}
return authenticate;
}
}
我正在尝试在 spring 安全文件中执行此操作:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:s="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<s:http auto-config="true">
<s:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<s:intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<s:intercept-url pattern="/**" access="ROLE_USER" />
<s:intercept-url pattern="/" access="ROLE_USER" />
<s:form-login login-page="/login" default-target-url="/getemp"/>
<s:logout logout-success-url="/logout" />
</s:http>
<s:authentication-manager>
<s:authentication-provider ref="adAuthenticationProvider"/>
</s:authentication-manager>
<bean id="adAuthenticationProvider"
class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<constructor-arg value="*********" />
<constructor-arg value="************" />
<property name="convertSubErrorCodesToExceptions" value="true"/>
</bean>
</beans>
显示的html登录页面是:
使用用户名和密码登录(自定义页面)
<form method="POST" action="j_spring_security_check" name="f">
<table>
<tbody><tr>
<td>User:</td>
<td><input type="text" value="" name="j_username">
</td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="j_password">
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="submit" name="submit">
</td>
</tr>
<tr>
<td colspan="2"><input type="reset" name="reset">
</td>
</tr>
</tbody></table>
</form>
</body>
早些时候我在尝试 filterbasedLdapAuthenticator ann 至少得到了一个例外。现在,当我尝试登录时:控制台上没有显示任何内容 - 我再次进入登录页面。我哪里会出错。