여러 진입점을 갖도록 Spring Security 3.x 구성
Spring Security 3.x를 사용하여 프로젝트에 대한 사용자 인증을 처리해 왔으며 지금까지 완벽하게 작동했습니다.
저는 최근에 새로운 프로젝트에 대한 요구 사항을 받았습니다.이 프로젝트에서는 LDAP에 대해 직원을 인증하고 데이터베이스에 대해 고객을 인증하는 두 가지 사용자 인증 세트가 필요합니다.Spring Security에서 이를 구성하는 방법에 대해 약간 당황스럽습니다.
제 초기 아이디어는 다음 필드가 있는 로그인 화면을 만드는 것이었습니다.
- 라디오 단추 필드 - 사용자가 직원인지 고객인지 선택할 수 있습니다.
j_username
사용자 필드.j_password
암호 필드.
사용자가 "직원"을 선택한 경우 Spring Security에서 LDAP에 대해 인증확인을 수행하고, 그렇지 않으면 자격 증명이 데이터베이스에 대해 인증확인됩니다.는 그 이 하만지, 문양제출것것다입니는이라될식이로 제출된다는 것입니다./j_spring_security_check
구현된 사용자 지정 인증 공급자에게 라디오 단추 필드를 보낼 수 없습니다.▁sub▁form▁relying▁thans▁need▁on▁my▁two▁themission▁url▁rather▁default다이니입것▁i▁is제▁thought▁probably▁initial할요필▁url출제식기양초의 두 개의 양식 제출 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의 아이디어를 통합했지만, 일부 사용되지 않는 클래스를 대체해야 합니다.제가 는 필터 되어 있지 않은 것처럼 것이 . 왜냐하면 는 계속해서 Spring Security에 등록되어 있기 입니다. 왜냐하면 계속해서 발생하기 때문입니다.Error 404: SRVE0190E: File not found: /j_spring_security_check_for_employee
은 내직감입니다.springSecurityFilterChain
빈이 제대로 연결되지 않아 사용자 정의 필터가 전혀 사용되지 않습니다.
저는 , WebSphere, WebSphere를 .com.ibm.ws.webcontainer.invokefilterscompatibility=true
서버에 설정된 속성입니다.인 기값을수있습다니누를본▁the다니를 누를 수 /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의 기술에 대한 솔루션
여기서 한 것 . 제, 가여기서문해다고생결각합니다했네제를▁okay,다생니합각▁here네.가지고 있는 대신에EmployeeCustomAuthenticationProvider
인 채무에의다니합존행에 합니다.UsernamePasswordAuthenticationToken
가 내만든을 만들었습니다.EmployeeUsernamePasswordAuthenticationToken
을 위해, 제가 만든 처럼, 내을만위것, 가든처럼해.CustomerUsernamePasswordAuthenticationToken
위해서CustomerCustomAuthenticationProvider
다음 공급자는 그면이공다재정합다니의음을급가러자를 합니다.supports()
:-
고객 사용자 정의AuthenticationProvider 클래스
@Override
public boolean supports(Class<? extends Object> authentication) {
return (CustomerUsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
직원 사용자 정의AuthenticationProvider 클래스
@Override
public boolean supports(Class<? extends Object> authentication) {
return (EmployeeUsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
내 AuthenticationFilter
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
직원과 고객을 위해 서로 다른 토큰을 만들어야 합니다.
다음은 단계입니다.
기본값 사용
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>
몇 가지를 정의할 수 있습니다.AuthenticationProcessingFilter
필터각각의 URL은 /j_security_check_for_employee 및 /j_security_check_for_customer와 같이 서로 다를 수 있습니다.다음은 이 아이디어를 보여주는 보안 응용프로그램 컨텍스트의 예입니다.
<bean id="myfilterChainProxy" class="org.springframework.security.util.FilterChainProxy">
<security:filter-chain-map pathType="ant">
<security:filter-chain pattern="/**" filters="authenticationProcessingFilterForCustomer, authenticationProcessingFilterForEmployee, ..." />
</security:filter-chain-map>
</bean>
<bean id="authenticationProcessingFilterForCustomer" class="org.springframework.security.web.authentication.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManagerForCustomer"/>
<property name="filterProcessesUrl" value="/j_security_check_for_customer"/>
</bean>
<bean id="authenticationProcessingFilterForEmployee" class="org.springframework.security.web.authentication.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManagerForEmployee"/>
<property name="filterProcessesUrl" value="/j_security_check_for_employee"/>
</bean>
<bean id="authenticationManagerForCustomer" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<bean class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService">
<ref bean="customerUserDetailsServiceThatUsesDB"/>
</property>
</bean>
</list>
</property>
</bean>
<bean id="authenticationManagerForEmployee" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService">
<ref bean="employeeUserDetailsServiceThatUsesLDAP"/>
</property>
</bean>
</list>
</property>
</bean>
보다시피, 이 시나리오에서는 또한 다음과 같이 다릅니다.UserDetailService
s - DB 인증 및 LDAP용입니다.
고객과 직원(특히 다른 인증 전략을 사용하는 경우)에 대해 서로 다른 인증 URL을 가지는 것이 좋다고 생각합니다.다른 로그인 페이지를 사용할 수도 있습니다.
Java 구성 참조용
나는 여기에 xml 구성에 익숙하지 않은 사람들을 돕기 위해 동일한 기술을 구현하는 Java 구성 방법을 쓰고 싶지만, Java 구성 코드의 긴 답변으로 이 스레드 뷰티를 가로채고 싶지 않습니다.
Java 구성(주석 기반)으로 동일한 결과를 얻기를 원하는 사람은 아래의 자체 답변 질문 링크를 참조할 수 있으며 답변에서 코드에 대한 내 github 저장소 링크를 찾을 수 있습니다.
주석 기반 구성 코드의 경우 여기에서 내 대답을 참조하십시오. 다른 UsernamePasswordAuthToken을 사용하는 다중 인증 공급자는 폴백 인증 없이 다른 로그인 양식을 인증합니다.
이 정보는 DB에 저장할 수 있습니다.예를 들어 다음과 같은 열을 가질 수 있습니다.ldap_auth
에Users
표. 제 다른 답변(예를 들어 있습니다(예를 들어).
.UserService
클래스는 제가 실제로 이 LDAP 플래그를 테스트하고 LDAP 또는 데이터베이스에서 사용자 암호를 가져온다는 것을 알게 될 것입니다.
또 나야 :) 다음과 같은 필터를 사용해 볼 수 있습니까:
<sec:http auto-config="true">
...
<sec:custom-filter ref="authenticationProcessingFilterForCustomer" after="FIRST"/>
<sec:custom-filter ref="authenticationProcessingFilterForEmployee" after="FIRST"/>
</sec:http>
콩을 springSecurityFilterChain
.
언급URL : https://stackoverflow.com/questions/4783063/configuring-spring-security-3-x-to-have-multiple-entry-points
'programing' 카테고리의 다른 글
빠른 읽기 전용 외부, 읽기 쓰기 내부 속성 (0) | 2023.08.09 |
---|---|
PHP - 배열 내부에서 배열을 병합하는 방법 (0) | 2023.08.09 |
Android Studio에서 작성한 프로젝트에서 사용자 지정 글꼴을 사용하는 방법 (0) | 2023.08.09 |
브라우저에서 클라이언트 표준시 가져오기 (0) | 2023.08.09 |
사용자 지정 PowerShell 모듈을 원격 세션으로 가져오는 방법은 무엇입니까? (0) | 2023.08.09 |