gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 13:53:48 30 4
gpt4 key购买 nike

我一直在使用 Spring Security 3.x 来处理我的项目的用户身份验证,到目前为止,它运行完美。

我最近收到了一个新项目的要求。在这个项目中,它需要两组用户身份验证:一组根据 LDAP 对员工进行身份验证,另一组根据数据库对客户进行身份验证。我对如何在 Spring Security 中配置它感到有些困惑。

我最初的想法是创建一个包含以下字段的登录屏幕:-

  • 单选按钮字段 - 供用户选择他们是员工还是客户。
  • j_username用户字段。
  • j_password密码字段。

  • 如果用户选择“员工”,那么我希望 Spring Security 根据 LDAP 对他们进行身份验证,否则凭据将根据数据库进行身份验证。但是,问题是表单会提交到 /j_spring_security_check我无法将单选按钮字段发送到我实现的自定义身份验证提供程序。我最初的想法是我可能需要两个表单提交 URL,而不是依赖默认的 /j_spring_security_check .每个 URL 将由不同的身份验证提供程序处理,但我不确定如何在 Spring Security 中配置它。

    我知道在 Spring Security 中,我可以配置回退身份验证,例如,如果 LDAP 身份验证失败,那么它将回退到数据库身份验证,但这不是我在这个新项目中要拍摄的内容。

    有人可以分享我应该如何在 Spring Security 3.x 中配置它吗?

    谢谢你。

    更新 - 01-28-2011 - @EasyAngel 的技术

    我正在尝试执行以下操作:-
  • 员工表单登录提交到 /j_spring_security_check_for_employee
  • 客户表单登录提交至 /j_spring_security_check_for_customer

  • 我想要 2 个不同的表单登录的原因是允许我根据用户以不同的方式处理身份验证,而不是进行回退身份验证。就我而言,员工和客户可能具有相同的用户 ID。

    我采纳了@EasyAngel 的想法,但必须替换一些已弃用的类。我目前面临的问题是过滤器进程 URLS 似乎没有在 Spring Security 中注册,因为我不断收到 Error 404: SRVE0190E: File not found: /j_spring_security_check_for_employee .我的直觉是 springSecurityFilterChain bean 没有正确连接,因此我的自定义过滤器根本没有使用。

    顺便说一下,我正在使用 WebSphere 并且我确实有 com.ibm.ws.webcontainer.invokefilterscompatibility=true在服务器中设置的属性。我可以点击默认值 /j_spring_security_check没有问题。

    这是我完整的安全配置:-

    <?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 Security 3.x。

    谢谢你。

    更新 01-29-2011 - @Ritesh 的技术

    好的,我设法让@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>

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

    谢谢你。

    更新 - @Ritesh 技术的解决方案

    好的,我想我已经解决了这里的问题。而不是拥有 EmployeeCustomAuthenticationProvider依赖默认 UsernamePasswordAuthenticationToken , 我创建了 EmployeeUsernamePasswordAuthenticationToken为此,就像我创建的一样 CustomerUsernamePasswordAuthenticationTokenCustomerCustomAuthenticationProvider .然后这些提供者将覆盖 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!经过几天的挫折后,它现在可以完美运行!

    希望这篇文章能够帮助那些和我在这里做同样事情的人。

    最佳答案

    您不需要创建 /j_spring_security_check_for_employee/j_security_check_for_customer filterProcessingUrl .

    默认的单选按钮字段想法可以正常工作。

    在自定义登录LoginFilter ,您需要为员工和客户创建不同的 token 。

    以下是步骤:

  • 使用默认 UsernamePasswordAuthenticationToken用于员工登录。
  • 创建 CustomerAuthenticationToken用于客户登录。扩展 AbstractAuthenticationToken所以它的类类型不同于 UsernamePasswordAuthenticationToken .
  • 定义自定义登录过滤器:
    <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 EmployeeCustomAuthenticationProvider 中的方法支持UsernamePasswordAuthenticationToken .
  • 覆盖 supports CustomerCustomAuthenticationProvider 中的方法支持CustomerAuthenticationToken .
    @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>
  • 关于java - 将 Spring Security 3.x 配置为具有多个入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4783063/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com