spring-security + ldap的认证配置

来源:互联网 发布:淘宝如何抢秒杀商品 编辑:程序博客网 时间:2024/06/06 01:09

使用spring-security模块

1.      Maven依赖和版本

2.      配置xml和对象

2.1. 配置ldap

2.2. 配置登录后处理

2.3  配置过滤器

3.      重定向和反向代理

4.      Cookie的path设置

5.      配置过程中遇到的问题

 

1.      Maven的依赖和版本

在引入spring-security依赖时.最开始使用的4.1.1.RELEASE,SPRING使用的4.2.6.RELEASE,结果一直报有对象找不到.后来改成spring-security.4.0.3.RELEASE后解决.最后springframework使用的4.2.6.RELEASE,spring-security使用的4.0.3.RELEASE.

<!--spring-security-->
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-web</artifactId>
  <version>${spring-security.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-config</artifactId>
  <version>${spring-security.version}</version>
</dependency>
<!--https://mvnrepository.com/artifact/org.springframework.security/spring-security-ldap-->
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-ldap</artifactId>
  <version>${spring-security.version}</version>
</dependency>
<!--./spring-security-->

2.      application-security.xml配置

<beansxmlns="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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd

">

 

         <s:http use-expressions="true" entry-point-ref="restAuthenticationEntryPoint">

           <s:csrf disabled="true"/>

           <s:intercept-url pattern="/login*" access="permitAll"/>

           <s:intercept-url pattern="/*" access="authenticated"/>

           <s:form-login authentication-success-handler-ref="mySuccessHandler" authentication-failure-handler-ref="myFailureHandler"  default-target-url="/t.html"/>

           <s:logout/>

</s:http>

 

<bean id="mySuccessHandler" class="com.xx.xx.security.RestAuthenticationSuccessHandler">

           <property name="defaultTargetUrl"  value="/index.html"/>

</bean>

<bean id="myFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"/>

 

<s:authentication-manager>

           <s:authentication-providerref='secondLdapProvider' />

</s:authentication-manager>

 

<!-- This bean points at the embedded directory server created by the ldap-server element above  -->

<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">

           <constructor-arg value="ldap://xxxxxx:389/dc=xxxx,dc=com"/>

           <property name="userDn" value="xxxx"></property>

           <property name="password"  value="xxxx"></property>

 

         </bean>

<bean id="secondLdapProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">

           <constructor-arg>

                    <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">

                             <constructor-argref="contextSource" />

                             <property name="userSearch">

                                       <bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">

                                         <constructor-arg index="0"value="OU=xx账户"/>

                                         <constructor-arg index="1"value="(sAMAccountName={0})"/>

                                         <constructor-arg index="2"ref="contextSource" />

                                       </bean>

                             </property>

                    </bean>

           </constructor-arg>

 

</bean>

 

 

</beans>

 

2.1  ldap配置

配置ldap验证登录.首先需要配置org.springframework.security.ldap.DefaultSpringSecurityContextSource
, 在构造方法里配置ldap连接,然后注入userDn,password两个值,即连接的用户名和密码.这里既可以使用上面的contextSource,也可以使用org.springframework.ldap.core.support.LdapContextSource ,两个配置contextSource的类都可以.
接下把contextSource注入ldapProvider的构造方法里.同时要传入属性值userSearch.userSearch是登录验证时,如何查询用户的.在这里要规定查询范围. org.springframework.security.ldap.search.FilterBasedLdapUserSearch 构造函数需要传入三个参数:0-查询基础(确定在什么范围查找),1-查询过滤字段(根据什么字段查找),2-contextSource(用来建立ldap连接).配置完ldap相关内容后将ldapprovider 注入authentication-manager.
 
这里提一下ldap中的一些属性.CN ( Common Name ),OU (Organizational Unit),DC(Domain Component)都是ldap服务器中区别名称DN ( distinguished name )
例如:CN=test,OU=developer,DC=domainname,DC=com 在上面的代码中 cn=test 可能代表一个用户名,ou=developer 代表一个 active directory 中的组织单位。这句话的含义可能就是说明 test 这个对象处在domainname.com 域的 developer 组织单元中.
2.2  配置登录后处理
     刚刚配置了如何认证用户,现在配置哪些需要认证.
     http元素里配置需要认证的接口.
     intecept-url里写上pattern以及access级别,需要认证的是authenticated,不需要的是permitAll. entry-point-ref是认证失败后的操作(实现AuthenticationEntryPoint接口的 commence方法,restful接口返回401,访问页面则跳转到登录页面).
form-login提供表单登录页,访问xx/login就能看到. default-target-url是认证成功默认跳转地址.authentication-success-handler-ref是登录成功的方法(这里重写SimpleUrlAuthenticationSuccessHandler的onAuthenticationSuccess方法来定制认证成功后的操作),使用SimpleUrlAuthenticationSuccessHandler,则之前的default-target-url的地址就失效了, authentication-failure-handler-ref是登录失败的方法,使用SimpleUrlAuthenticationFailureHandler.
public class RestAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{    private RequestCache requestCache = new HttpSessionRequestCache();    @Override    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException    {        final SavedRequest savedRequest = requestCache.getRequest(request,response);        //第一次访问        if(savedRequest == null)        {            clearAuthenticationAttributes(request);           response.sendRedirect("/t.html");            return;        }        final String targetUrlParameter = getTargetUrlParameter();        if(isAlwaysUseDefaultTargetUrl()|| (targetUrlParameter!=null&& StringUtils.hasText(request.getParameter(targetUrlParameter))))        {            requestCache.removeRequest(request,response);            clearAuthenticationAttributes(request);            return;        }        clearAuthenticationAttributes(request);//         Use the DefaultSavedRequest URL         final String targetUrl = savedRequest.getRedirectUrl();         logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);        // getRedirectStrategy().sendRedirect(request, response, targetUrl);
response.sendRedirect(targetUrl);
    }    public void setRequestCache(RequestCache requestCache)    {        this.requestCache = requestCache;    }}
 
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint{    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException    {   /*if  ajax request return 401 Unauthorized            else rediect to specific page        */        if("XMLHttpRequest".equals(httpServletRequest.getHeader("x-requested-with")))           httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Unauthorized");        else            httpServletResponse.sendRedirect("/xx/login");    }}
2.3  配置过滤器
最后在web.xml里配置过滤器
<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>
 
以上这些配置完后就可以使用spring-security的认证功能了.
 
 

3.      重定向和反向代理

在使用中,由于我们的项目是使用的前后端分离,后端是有多个application的.所以在认证所在app里重定向相对地址会变成http://xxx/projectName/index.html.这样就不能访问到真的t.html(正确地址应该是http://xxx/index.html).而如果写全地址,则以后域名更改后又要改代码,会比较麻烦.我们项目是使用的apache.所以通过apache的反向代理来进行网址的转化.原来是这么配置的

ProxyPassReverse        /xx               http://127.0.0.1:8680/xx

改为

         ProxyPassReverse        /                       http://127.0.0.1:8680/

 
4.  Cookie的path配置
同上的原因,所以认证生成的cookie的path是/xx,也就是在其他页面无效,只能在http://localhost/xx下有效.cookie的作用域是由应用容器决定的,这方面spring好像不大好改.所以要改web.xml将path变成全局的.如下:
<session-config>  <cookie-config>    <path>/</path>  </cookie-config></session-config>
 
5.  配置过程中遇到的问题
其实在配置过程中碰到需要报错,没能一一记下,但是晃晃悠悠也都解决或者避过去了.很多问题之前都遇到过,但是身处山中不知山,在面对没接触的东西的时候,会有怕麻烦和未知的恐惧,所以很多本来应该能看出来的问题也兜了一些圈子.
404 pageNotFound 这就是Controller里没有这个mapping,没有其他原因,具体是名字写错了,还是没有被注入applicationContext都有可能.遇到这个问题直接找spring加载初始化的问题,和spring-security无关.
302 Found 这是ajax请求遇到重定向页面报的错.如果是页面访问,它会正常重定向到目标页面.但是ajax访问会返回成功码302,还有重定向的页面内容.这里提一句,一般jquery的ajax请求会在header多一个属性x-requested-with: XMLHttpRequest可以通过这个来区别ajax和普通请求.
  重定向时 spring-web的DefaultRedirectStrategy重定向相对地址会给路径中间加上项目名,HttpServletRequest的重定向则不会
 
 
0 0
原创粉丝点击