目前我已经编写了一个带有http基本登录的Spring Ldap身份验证和授权模块,但现在我需要从请求中的cookie中获取用户名和密码,并将它们绑定到ldap进行身份验证。
以下是我的websecurity配置类
@Configuration
@EnableWebSecurity
public class LdapSecurity extends WebSecurityConfigurerAdapter {
@Autowired
CustomLdapAuthoritiesPopulator customLdapAuthoritiesPopulator;
@Value("${ldap.config.url:ldap://192.168.1.50:389}")
private String LDAP_URL;
@Value("${ldap.config.managerdn:uid=admin,cn=users,cn=accounts,dc=example,dc=test}")
private String MANAGER_DN;
@Value("${ldap.config.managerpwd:admin123}")
private String MANAGER_PWD;
@Value("${ldap.config.basedn:cn=users,cn=accounts,dc=example,dc=test}")
private String SEARCH_BASE;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.httpBasic().
and().authorizeRequests().
anyRequest().permitAll().
and().
csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.ldapAuthentication().contextSource().url(LDAP_URL)
.managerDn(MANAGER_DN)
.managerPassword(MANAGER_PWD)
.and()
.userSearchBase(SEARCH_BASE)
.userSearchFilter("uid={0}")
.ldapAuthoritiesPopulator(customLdapAuthoritiesPopulator);
}
}
以下是我的CustomLdapAuthoritiesPopulator类
@Component
public class CustomLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {
String[] groups = userData.getStringAttributes("memberof");
List<String> wordList = Arrays.asList(groups);
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String string : wordList) {
if(string.toLowerCase().contains("cn=permissions")){
String parts[] = string.split(",");
String autho[]=parts[0].split("cn=");
System.out.println(autho[1]);
authorities.add(new SimpleGrantedAuthority(autho[1]));
}
}
return authorities;
}
}
提前致谢
答案 0 :(得分:2)
最后,我通过在BasicAuthenticationFilter之前使用Filter来解决这个问题。以下是我修改过的LdapSecurity类。
@Configuration
@EnableWebSecurity
public class LdapSecurity extends WebSecurityConfigurerAdapter {
@Autowired
CustomLdapAuthoritiesPopulator customLdapAuthoritiesPopulator;
@Autowired
AuthFilter authFilter;
@Value("${ldap.config.url:ldap://192.168.1.50:389}")
private String LDAP_URL;
@Value("${ldap.config.managerdn:uid=admin,cn=users,cn=accounts,dc=example,dc=test}")
private String MANAGER_DN;
@Value("${ldap.config.managerpwd:admin123}")
private String MANAGER_PWD;
@Value("${ldap.config.basedn:cn=users,cn=accounts,dc=example,dc=test}")
private String SEARCH_BASE;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.addFilterBefore(authFilter,BasicAuthenticationFilter.class);
httpSecurity.httpBasic().and().
authorizeRequests().
anyRequest().authenticated().
and().
csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.ldapAuthentication().contextSource().url(LDAP_URL)
.managerDn(MANAGER_DN)
.managerPassword(MANAGER_PWD)
.and()
.userSearchBase(SEARCH_BASE)
.userSearchFilter("uid={0}")
.ldapAuthoritiesPopulator(customLdapAuthoritiesPopulator);
}
}
以下是扩展GenericFilter的自定义AuthFilter类
@Component
public class AuthFilter extends GenericFilter{
private static final long serialVersionUID = 1L;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(req);
Cookie[] cookies = mutableRequest.getCookies();
if(cookies!=null)
for (int i = 0; i < cookies.length; i++) {
if(cookies[i].getName().equals("nginxauth")){
String auth=cookies[i].getValue().replace("\"", "");
System.out.println(auth);
mutableRequest.putHeader("Authorization","Basic "+auth);
}
}
chain.doFilter(mutableRequest, response);
}
}
下面是MutableRequestClass
final class MutableHttpServletRequest extends HttpServletRequestWrapper {
// holds custom header and value mapping
private final Map<String, String> customHeaders;
public MutableHttpServletRequest(HttpServletRequest request){
super(request);
this.customHeaders = new HashMap<String, String>();
}
public void putHeader(String name, String value){
this.customHeaders.put(name, value);
}
public String getHeader(String name) {
// check the custom headers first
String headerValue = customHeaders.get(name);
if (headerValue != null){
return headerValue;
}
// else return from into the original wrapped object
return ((HttpServletRequest) getRequest()).getHeader(name);
}
public Enumeration<String> getHeaderNames() {
// create a set of the custom header names
Set<String> set = new HashSet<String>(customHeaders.keySet());
// now add the headers from the wrapped request object
Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();
while (e.hasMoreElements()) {
// add the names of the request headers into the list
String n = e.nextElement();
set.add(n);
}
// create an enumeration from the set and return
return Collections.enumeration(set);
}
}