我最终得到的解决方案是基于这个答案:https://stackoverflow.com/a/1422202/711031。我使用以下FilteredRequest 实现:
public class LoginDomainCutFilter implements Filter {
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(new FilteredRequest(request), response);
}
private static class FilteredRequest extends HttpServletRequestWrapper {
public FilteredRequest(ServletRequest request) {
super((HttpServletRequest) request);
}
public String getParameter(String paramName) {
String value = super.getParameter(paramName);
if ("j_username".equals(paramName)) {
value = cutSuffix(value, "@mail.domain.com");
value = cutSuffix(value, "@domain.com");
}
return value;
}
private String cutSuffix(String value, String suffix) {
if (value.endsWith(suffix)) value = value.substring(0, value.length() - suffix.length());
return value;
}
}
}
在这种情况下,我们应该在web.xml 注册我们的过滤器在 Spring Security 过滤器之前:
<filter>
<filter-name>loginDomainCutFilter</filter-name>
<filter-class>org.mydomain.myapp.LoginDomainCutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginDomainCutFilter</filter-name>
<url-pattern>/j_spring_security_check</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
最后一步是将 LDAP 搜索过滤器中的 (mail={0}) 更改为 (mail={0}@*):
<beans:bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<beans:constructor-arg index="0" value="ou=users,ou=myorgunit"/>
<beans:constructor-arg index="1" value="(mail={0}@*)"/>
<beans:constructor-arg index="2" ref="contextSource"/>
<beans:property name="searchSubtree" value="true"/>
</beans:bean>
请注意,该解决方案的副作用是 Spring Security 用户名将不再包含 @domain 后缀,因此在需要显示电子邮件时应手动添加。但是,您应该决定哪个是主要的。
您还应该注意,过滤器不会影响包含另一个域后缀或根本没有后缀的用户名。这样做是有目的的,您可以为此添加一个简单的检查。
现在用户可以使用user@mail.domain.com、user@domain.com 甚至user 登录。如果您不喜欢后者的“奖励行为”,您还可以添加支票。