我一直在使用Spring Security 3.x来为我的项目处理用户身份验证,到目前为止,它已经完美地工作了。
我最近收到了一个新项目的要求。在此项目中,需要两套用户身份验证:一套用于根据LDAP验证员工,另一套用于根据数据库验证客户。我对如何在Spring Security中进行配置感到有些困惑。
我最初的想法是创建一个具有以下字段的登录屏幕:
j_username
j_password
Spring Security
/j_spring_security_check
URL /j_spring_security_check
我知道在Spring Security中,我可以配置回退身份验证,例如,如果LDAP身份验证失败,那么它将回退至数据库身份验证,但这不是我在这个新项目中要解决的问题。
有人可以分享我在Spring Security 3.x中应该如何配置它吗?
谢谢。
我正在尝试执行以下操作:
/j_spring_security_check_for_employee
/j_spring_security_check_for_customer
我结合了@EasyAngel的想法,但必须替换一些不推荐使用的类。我目前面临的问题是,由于我不断获取,两个过滤器进程似乎都没有在Spring Security中注册URL Error 404: SRVE0190E: File not found: /j_spring_security_check_for_employee。我的直觉是springSecurityFilterChainBean接线不正确,因此根本没有使用我的自定义过滤器。
@EasyAngel
URL Error 404: SRVE0190E: File not found: /j_spring_security_check_for_employee
springSecurityFilterChainBean
顺便说一下,我正在使用WebSphere,并且确实com.ibm.ws.webcontainer.invokefilterscompatibility=true在服务器中设置了属性。我可以/j_spring_security_check毫无问题地达到默认值。
WebSphere
com.ibm.ws.webcontainer.invokefilterscompatibility=true
这是我完整的安全配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:sec="http://www.springframework.org/schema/security" 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.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <sec:http auto-config="true"> <sec:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" default-target-url="/welcome.jsp" always-use-default-target="true" /> <sec:logout logout-success-url="/login.jsp" /> <sec:intercept-url pattern="/employee/**" access="ROLE_EMPLOYEE" /> <sec:intercept-url pattern="/customer/**" access="ROLE_CUSTOMER" /> <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> </sec:http> <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> <sec:filter-chain-map path-type="ant"> <sec:filter-chain pattern="/**" filters="authenticationProcessingFilterForEmployee, authenticationProcessingFilterForCustomer" /> </sec:filter-chain-map> </bean> <bean id="authenticationProcessingFilterForEmployee" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManagerForEmployee" /> <property name="filterProcessesUrl" value="/j_spring_security_check_for_employee" /> </bean> <bean id="authenticationProcessingFilterForCustomer" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManagerForCustomer" /> <property name="filterProcessesUrl" value="/j_spring_security_check_for_customer" /> </bean> <bean id="authenticationManagerForEmployee" class="org.springframework.security.authentication.ProviderManager"> <property name="providers"> <list> <ref bean="employeeCustomAuthenticationProvider" /> </list> </property> </bean> <bean id="authenticationManagerForCustomer" class="org.springframework.security.authentication.ProviderManager"> <property name="providers"> <list> <ref bean="customerCustomAuthenticationProvider" /> </list> </property> </bean> <bean id="employeeCustomAuthenticationProvider" class="ss.EmployeeCustomAuthenticationProvider"> <property name="userDetailsService"> <bean class="ss.EmployeeUserDetailsService"/> </property> </bean> <bean id="customerCustomAuthenticationProvider" class="ss.CustomerCustomAuthenticationProvider"> <property name="userDetailsService"> <bean class="ss.CustomerUserDetailsService"/> </property> </bean> <sec:authentication-manager> <sec:authentication-provider ref="employeeCustomAuthenticationProvider" /> <sec:authentication-provider ref="customerCustomAuthenticationProvider" /> </sec:authentication-manager> </beans>
我在这里开始赏金,因为我似乎已经好几天都无法正常工作了……挫败感是这个词。我希望有人指出问题,或者如果您可以(以代码形式)向我展示一种更好或更干净的方法来解决此问题。
我正在使用Spring Security3.x。
你无需创建/j_spring_security_check_for_employee和/j_security_check_for_customer filterProcessingUrl。
/j_security_check_for_customer filterProcessingUrl
默认情况下,可以与单选按钮字段提示配合使用。
在定制登录中LoginFilter,你需要为员工和客户创建不同的令牌。
LoginFilter
步骤如下:
使用默认值UsernamePasswordAuthenticationToken进行员工登录。
UsernamePasswordAuthenticationToken
创建CustomerAuthenticationToken用于客户登录。进行扩展AbstractAuthenticationToken,以使其类类型不同于UsernamePasswordAuthenticationToken。
CustomerAuthenticationToken
AbstractAuthenticationToken
定义自定义登录过滤器:
<security:http> <security:custom-filter position="FORM_LOGIN_FILTER" ref="customFormLoginFilter" /> </security:http>
customFormLoginFilter
attemptAuthentication
if (radiobutton_param value employee) { UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(whatever); return getAuthenticationManager().authenticate(authRequest); } else if (radiobutton_param value customer) { CustomerAuthenticationToken authRequest = new CustomerAuthenticationToken(username, password); setDetails(whatever); return getAuthenticationManager().authenticate(authRequest); }
支持重写supports方法。EmployeeCustomAuthenticationProviderUsernamePasswordAuthenticationToken
supports
EmployeeCustomAuthenticationProviderUsernamePasswordAuthenticationToken
支持重写supports方法。CustomerCustomAuthenticationProviderCustomerAuthenticationToken
CustomerCustomAuthenticationProviderCustomerAuthenticationToken
@Override public boolean supports(Class<?> authentication) { return (CustomerAuthenticationToken.class.isAssignableFrom(authentication)); }
authentication-manager
<security:authentication-manager alias="authenticationManager"> <security:authentication-provider ref='employeeCustomAuthenticationProvider ' /> <security:authentication-provider ref='customerCustomAuthenticationProvider ' /> </security:authentication-manager>