我目前正在开发一个涉及GWT 2.5 + Spring 3.1 + Hibernate 3.10的项目。
Web应用程序目前正在生产中并且具有受保护的资源。 为了安全起见,我们使用带有LDAP身份验证的Spring security 3.1。
我们目前有一个表单登录,我们填写用户名和密码并重定向到适当的html页面(在成功处理程序中),如果一切正常,否则我们会重定向到失败页面(由于失败)处理程序)。
现在,客户端希望保留此功能并添加新的功能,包括直接在URL中添加用户名和密码,而不通过表单登录。如果凭据正常,这将成功进行身份验证,否则将重定向到失败页面。
我已经阅读了很多关于这个主题的内容,但我无法让事情发挥作用。
这是我现有的spring-security.xml文件:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
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">
<!-- ================================================== -->
<!-- SECURITE -->
<!-- ================================================== -->
<security:http pattern="/jsp/static/**" security="none"/>
<security:http pattern="/PIE.htc" security="none"/>
<security:http pattern="/ConsultationAccords.css" security="none"/>
<!--Allow everyone to access the JSP login page -->
<security:intercept-url pattern="/app/auth/**" access="permitAll"/>
<security:intercept-url pattern="/jsp/*" access="permitAll"/>
<!-- Limitation d'accès aux différentes partie de l'appli, les pattern sont basés sur les déclaration dans le fichier web.xml -->
<security:intercept-url pattern="/consultationaccords/**" access="isAuthenticated()"/>
<security:intercept-url pattern="/DownloadCourrierServ" access="isAuthenticated()"/>
<security:intercept-url pattern="/*.gupId" access="isAuthenticated()"/>
<security:intercept-url pattern="/DownloadServ" access="isAuthenticated()"/>
<security:intercept-url pattern="/ConsultationAccords.html" access="isAuthenticated()"/>
<security:intercept-url pattern="/ExportServ" access="isAuthenticated()"/>
<security:intercept-url pattern="/ManuelUtilisateurServ" access="isAuthenticated()"/>
<security:intercept-url pattern="/**" access="denyAll" />
<!-- If the user is authorized, he will be redirected to the success-handler.
The sucess-handler is responsible of interpreting what to do next.
Same principle with the failure-handler -->
<security:form-login authentication-success-handler-ref="authenticationSuccessHandler" authentication-failure-handler-ref="authenticationFailureHandler" />
<!-- These are the login and logout URLs -->
<security:logout invalidate-session="true" logout-success-url="/app/auth/login" logout-url="/app/auth/logout"/>
<security:session-management invalid-session-url="/app/auth/login"/>
</security:http>
<!-- Point d'entrée pour indiquer à l'utilisateur qu'il doit s'authentifier d'abord -->
<beans:bean id="authenticationEntryPoint" class="fr.gouv.travail.consultationAccords.server.auth.GAAuthenticationEntryPoint" />
<!-- Handler appelé si l'utilisateur a été authetifié avec succès -->
<beans:bean id="authenticationSuccessHandler" class="fr.gouv.travail.consultationAccords.server.auth.GAAuthenticationSuccessHandler"/>
<!-- Handler appelé si l'authetification de l'utilisateur a échoué -->
<beans:bean id="authenticationFailureHandler" class="fr.gouv.travail.consultationAccords.server.auth.GAAuthenticationFailureHandler"/>
<!-- ================================================== -->
<!-- ********************************* -->
<!-- ================================================== -->
<security:authentication-manager>
<security:authentication-provider ref='ldapAuthProvider' />
</security:authentication-manager>
<!-- ================================================== -->
<!-- CONNEXION AU LDAP -->
<!-- ================================================== -->
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://${ldap.server_ip}:${ldap.server_port}"/>
<property name="userDn" value="${ldap.user_reader_account}" />
<property name="password" value="${ldap.password_reader_account}" />
</bean>
<!-- ================================================== -->
<!-- AUTHENTIFICATION + AUTORISATION -->
<!-- ================================================== -->
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource" />
<property name="userSearch">
<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="${ldap.user_base_search}"/>
<constructor-arg index="1" value="(uid={0}@${ldap.domain_name})"/>
<constructor-arg index="2" ref="contextSource" />
</bean>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource" />
<constructor-arg value="${ldap.group_base_search}" />
<property name="groupSearchFilter" value="(uniqueMember={0})"/>
<property name="rolePrefix" value="ROLE_"/>
<property name="searchSubtree" value="true"/>
<property name="convertToUpperCase" value="true"/>
<property name="groupRoleAttribute" value="${ldap.group_role_attribute}"/>
</bean>
</constructor-arg>
</bean>
我的web.xml的相关部分
<!-- The Spring Security Filter Chain -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!-- Pay attention to the url-pattern -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Front Controller for all Spring based servlets -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
/WEB-INF/spring-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Don't forget to declare a spring-servlet.xml -->
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
这就是我所做的:
声明并设置一个bean,它是UsernamePasswordAuthenticationFilter(带有成功处理程序,失败处理程序,身份验证管理器,usernameParameter和passwordParameter)
将其添加到security-http标记+配置位置为FIRST
我的web.xml包含springSecurityFilterChain
我修改了spring-security.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
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">
<!-- ================================================== -->
<!-- SECURITE -->
<!-- ================================================== -->
<security:http pattern="/jsp/static/**" security="none"/>
<security:http pattern="/PIE.htc" security="none"/>
<security:http pattern="/ConsultationAccords.css" security="none"/>
<security:http pattern="/app/auth/images/**" security="none"/>
<security:custom-filter ref="requestAuthenticationFilter" position="FIRST" />
<!--Allow everyone to access the JSP login page -->
<security:intercept-url pattern="/app/auth/**" access="permitAll"/>
<security:intercept-url pattern="/jsp/*" access="permitAll"/>
<!-- Limitation d'accès aux différentes partie de l'appli, les pattern sont basés sur les déclaration dans le fichier web.xml -->
<security:intercept-url pattern="/consultationaccords/**" access="isAuthenticated()"/>
<security:intercept-url pattern="/DownloadCourrierServ" access="isAuthenticated()"/>
<security:intercept-url pattern="/*.gupId" access="isAuthenticated()"/>
<security:intercept-url pattern="/DownloadServ" access="isAuthenticated()"/>
<security:intercept-url pattern="/ConsultationAccords.html" access="isAuthenticated()"/>
<security:intercept-url pattern="/ExportServ" access="isAuthenticated()"/>
<security:intercept-url pattern="/ManuelUtilisateurServ" access="isAuthenticated()"/>
<security:intercept-url pattern="/**" access="denyAll" />
<security:form-login authentication-success-handler-ref="authenticationSuccessHandler" authentication-failure-handler-ref="authenticationFailureHandler" />
<!-- These are the login and logout URLs -->
<security:logout invalidate-session="true" logout-success-url="/app/auth/login" logout-url="/app/auth/logout" />
<security:session-management invalid-session-url="/app/auth/login"/>
</security:http>
<beans:bean id="requestAuthenticationFilter" class="fr.gouv.travail.consultationAccords.server.auth.RequestAuthenticationFilter">
<beans:property name="usernameParameter" value="${ldap.user_request_param_direct_logging}" />
<beans:property name="passwordParameter" value="${ldap.password_request_param_direct_logging}" />
<beans:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" />
<beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<!-- Point d'entrée pour indiquer à l'utilisateur qu'il doit s'authentifier d'abord -->
<beans:bean id="authenticationEntryPoint" class="fr.gouv.travail.consultationAccords.server.auth.GAAuthenticationEntryPoint" />
<!-- Handler appelé si l'utilisateur a été authetifié avec succès -->
<beans:bean id="authenticationSuccessHandler" class="fr.gouv.travail.consultationAccords.server.auth.GAAuthenticationSuccessHandler"/>
<!-- Handler appelé si l'authetification de l'utilisateur a échoué -->
<beans:bean id="authenticationFailureHandler" class="fr.gouv.travail.consultationAccords.server.auth.GAAuthenticationFailureHandler"/>
<!-- ================================================== -->
<!-- ********************************* -->
<!-- ================================================== -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref='ldapAuthProvider' />
</security:authentication-manager>
<!-- ================================================== -->
<!-- CONNEXION AU LDAP -->
<!-- ================================================== -->
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://${ldap.server_ip}:${ldap.server_port}"/>
<property name="userDn" value="${ldap.user_reader_account}" />
<property name="password" value="${ldap.password_reader_account}" />
</bean>
<!-- ================================================== -->
<!-- AUTHENTIFICATION + AUTORISATION -->
<!-- ================================================== -->
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource" />
<property name="userSearch">
<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="${ldap.user_base_search}"/>
<constructor-arg index="1" value="(uid={0}@${ldap.domain_name})"/>
<constructor-arg index="2" ref="contextSource" />
</bean>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource" />
<constructor-arg value="${ldap.group_base_search}" />
<property name="groupSearchFilter" value="(uniqueMember={0})"/>
<property name="rolePrefix" value="ROLE_"/>
<property name="searchSubtree" value="true"/>
<property name="convertToUpperCase" value="true"/>
<property name="groupRoleAttribute" value="${ldap.group_role_attribute}"/>
</bean>
</constructor-arg>
</bean>
有可能实现这样的目标吗?如果是的话,你可以帮我解决这个问题吗?
非常感谢!
答案 0 :(得分:0)
首先,您需要定义自定义过滤器
package com.example;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import javax.servlet.*;
import java.io.IOException;
public class CustomAuthFilter implements Filter {
private AuthenticationManager authenticationManager;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String username = servletRequest.getParameter("username");
String password = servletRequest.getParameter("password");
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
Authentication successfulAuthentication;
try {
successfulAuthentication = authenticationManager.authenticate(authRequest);
} catch (Exception exception) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
SecurityContextHolder.getContext().setAuthentication(successfulAuthentication);
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
}
将此过滤器定义为spring bean
<bean id="customFilter" class="com.example.CustomAuthFilter">
<property name="authenticationManager" ref="authenticationManager" />
<bean>
将此过滤器添加到弹簧安全过滤器链
<security:http ...>
<custom-filter ref="customFilter" position="PRE_AUTH_FILTER" />
</security:http>