为了账号安全,请及时绑定邮箱和手机立即绑定

将Spring Security 3.x配置为具有多个入口点

将Spring Security 3.x配置为具有多个入口点

宝慕林4294392 2019-10-25 10:06:33
我一直在使用Spring Security 3.x来为我的项目处理用户身份验证,到目前为止,它已经完美地工作了。我最近收到了一个新项目的要求。在此项目中,需要两套用户身份验证:一套用于根据LDAP验证员工,另一套用于根据数据库验证客户。我对如何在Spring Security中进行配置感到有些困惑。我最初的想法是创建一个具有以下字段的登录屏幕:单选按钮字段-供用户选择是员工还是客户。j_username 用户字段。j_password 密码字段。如果用户选择“雇员”,那么我希望Spring Security根据LDAP对他们进行身份验证,否则,将根据数据库对凭据进行身份验证。但是,问题在于表单将被提交到,/j_spring_security_check并且我无法将单选按钮字段发送给实现的自定义身份验证提供程序。我最初的想法是,我可能需要两个表单提交URL,而不是依赖默认URL /j_spring_security_check。每个URL将由不同的身份验证提供程序处理,但是我不确定如何在Spring Security中进行配置。我知道在Spring Security中,我可以配置回退身份验证,例如,如果LDAP身份验证失败,则它将回退至数据库身份验证,但这不是我在这个新项目中要解决的问题。有人可以分享我在Spring Security 3.x中应该如何配置它吗?谢谢。
查看完整描述

3 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

好的,我设法使@Ritesh的方法非常接近我想要的工作。我有一个单选按钮,可让用户选择他们是客户还是员工。看来这种方法运作良好,有一个问题...


如果员工使用正确的凭据登录,则可以在...中按预期工作。

如果员工使用错误的凭据登录,则不允许他们在...中工作。

如果客户使用正确的凭据登录,则可以在...中按预期工作。

如果顾客有错凭据登录,认证回落到员工的认证...... 不起作用。这是有风险的,因为如果我选择客户身份验证并将其打入员工证书,它将也允许用户进入,这不是我想要的。

    <sec:http auto-config="false" entry-point-ref="loginUrlAuthenticationEntryPoint">

        <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:custom-filter position="FORM_LOGIN_FILTER" ref="myAuthenticationFilter"/>

    </sec:http>



    <bean id="myAuthenticationFilter" class="ss.MyAuthenticationFilter">

        <property name="authenticationManager" ref="authenticationManager"/>

        <property name="authenticationFailureHandler" ref="failureHandler"/>

        <property name="authenticationSuccessHandler" ref="successHandler"/>

    </bean>


    <bean id="loginUrlAuthenticationEntryPoint"

          class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">

        <property name="loginFormUrl" value="/login.jsp"/>

    </bean>


    <bean id="successHandler"

          class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">

        <property name="defaultTargetUrl" value="/welcome.jsp"/>

        <property name="alwaysUseDefaultTargetUrl" value="true"/>

    </bean>


    <bean id="failureHandler"

          class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">

        <property name="defaultFailureUrl" value="/login.jsp?login_error=1"/>

    </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 alias="authenticationManager">

        <sec:authentication-provider ref="customerCustomAuthenticationProvider"/>

        <sec:authentication-provider ref="employeeCustomAuthenticationProvider"/>

    </sec:authentication-manager>

</beans>

这是我更新的配置。我必须做一些非常小的调整,以防止身份验证回退,但我现在似乎无法弄清楚。


谢谢。


查看完整回答
反对 回复 2019-10-25
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

好吧,我想我已经解决了这个问题。无需EmployeeCustomAuthenticationProvider依赖默认值UsernamePasswordAuthenticationToken,我EmployeeUsernamePasswordAuthenticationToken为它创建了它,就像为它创建CustomerUsernamePasswordAuthenticationToken的那样CustomerCustomAuthenticationProvider。这些提供者将覆盖supports():-


CustomerCustomAuthenticationProvider类


@Override

public boolean supports(Class<? extends Object> authentication) {

    return (CustomerUsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));

}

EmployeeCustomAuthenticationProvider类


@Override

public boolean supports(Class<? extends Object> authentication) {

    return (EmployeeUsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));

}

MyAuthenticationFilter类


public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {


    ...


    UsernamePasswordAuthenticationToken authRequest = null;


    if ("customer".equals(request.getParameter("radioAuthenticationType"))) {

        authRequest = new CustomerUsernamePasswordAuthenticationToken(username, password);


    }

    else {

        authRequest = new EmployeeUsernamePasswordAuthenticationToken(username, password);

    }


    setDetails(request, authRequest);


    return super.getAuthenticationManager().authenticate(authRequest);

}

...还有WALAA!经过几天的挫败,它现在可以正常工作!


希望这篇文章能够对与我在这里做同样事情的人有所帮助。


查看完整回答
反对 回复 2019-10-25
  • 3 回答
  • 0 关注
  • 825 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信