使用Spring Security进行LDAP认证

Published on:

这里介绍一下如何是用Spring Security来做LDAP的认证,LDAP服务器只存放了用户的用户名和密码,没有角色等其他权限,所以这里介绍的是最简单的用户名密码认证。

下载spring-security相关JAR包

下面是gradle的脚本配置,需要下载spring-security和ldap相关的JAR包。

build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
String springSecurityVersion = "3.2.5.RELEASE"

dependencies {
...//other spring jars

//security
compile "org.springframework.security:spring-security-core:" + springSecurityVersion
compile "org.springframework.security:spring-security-web:" + springSecurityVersion
compile "org.springframework.security:spring-security-config:" + springSecurityVersion
compile "org.springframework.security:spring-security-ldap:" + springSecurityVersion
compile "org.springframework.ldap:spring-ldap-core:2.0.2.RELEASE"
}

配置web.xml

在web.xml配置filter,修改内容如下。

web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<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>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-security.xml</param-value>
</context-param>

创建spring-security.xml

在web.xml里面指定了Application启动时需要加载spring-security.xml文件,我们的LDAP认证主要就配置在这个文件里面。

spring-security.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:s="http://www.springframework.org/schema/security" xmlns:context="http://www.springframework.org/schema/context"
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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">

<context:property-placeholder location="classpath:app.properties" /> //1

<s:http pattern="/resources/**" security="none" /> //2
<s:http pattern="/login.html" security="none" /> //2

<s:http use-expressions="true">
<s:intercept-url pattern="/**" access="isAuthenticated()" /> //3
<s:form-login login-page="/login.html" //4
authentication-failure-url="/login.html?error=true" //5
username-parameter="j_username" password-parameter="j_password"/> //6
<s:anonymous />
<s:logout logout-success-url="/login.html?logout=true" /> //7
</s:http>

<s:ldap-server url="${ldap_server}" manager-dn="${ldap_user}"//8
manager-password="${ldap_password}" />

<s:authentication-manager>
<s:ldap-authentication-provider
user-dn-pattern="${ldap_user_dn_pattern}" /> //9
</s:authentication-manager>

</beans>
  1. 指定properties文件,下面的ldap信息都是从properties文件里面取得。
  2. 配置哪些资源和url不需要做认证,比如一些图片,js和css文件等,还有我们的login页面,如果把login页面也拦截的话,就做不了认证了。
  3. 指定其他url(/**)都需要做认证,isAuthenticated方法表示认证通过了才能访问该url。
  4. 指定登陆页面的地址,这里是相对路径,如果不指定login-page,认证时会自动调用spring-security的一个默认登陆页面。
  5. 指定认证失败后的url,这里我们使用同一个login页面,只是在url后面加上查询参数作为认证失败的标示。
  6. 指定login页面2个作用域,用户名和密码,需要和页面录入框的name相同。
  7. 指定登出/注销成功后的页面,这里我们还是使用login页面,在url后面加上logout参数作为标示。
  8. ldap服务器的配置信息,包括url, manager-dn和manager-password。
  9. 配置ldap的user-dn-pattern。

下面是app.properties的内容。

app.properties
1
2
3
4
5
# Ldap
ldap_server=ldap://your.ldap.server.com.:12356
ldap_user=cn=yourname,cn=Users,dc=ldap,dc=server,dc=com
ldap_password=123456
ldap_user_dn_pattern=uid={0},ou=staff,ou=people,o=ldap.server.com

创建登陆页面

创建用户登陆的Form,method为post,action为j_spring_security_check,用户录入框的name为j_username,密码录入框的name为j_password,这2个值与之前spring-security.xml里面配置的要保持一致。

login.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<form name="LoginForm" method="post" action="j_spring_security_check">
<div style="display: block;">
<div>
<h1>
<span class="ui-icon add"></span>用户登录
</h1>
</div>
<div class="content">
<div id="error" style="display: none; color: #c9302c" align="center">
<h3>认证失败,请重新登录</h3>
</div>
<div id="logout" style="display: none; color: #02547f" align="center">
<h3>已成功登出</h3>
</div>

<ul>
<li><label>
<span>用户名</span>
<input type="text" name="j_username">
</label></li>
<li><label>
<span>密码</span>
<input type="password" name="j_password">
</label></li>
</ul>
</div>
<div>
<button type="submit" name="logon" value="Logon">登录</button>
</div>
</div>
</form>

相关的js代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

if(getParameterByName("error")) {
$("#error").show();
}

if(getParameterByName("logout")) {
$("#logout").show();
}

如果需要的话,可以配置自己的logout页面,只需要一个Form就可以了,方法为post,action为j_spring_security_logout,只要提交了这个Form就可以成功登出了。

logout.html
1
<form action="j_spring_security_logout" method="post" id="logoutForm"></form>

更多Spring Security的信息请查阅: Spring Security Reference

赞赏

Comments