私はSpring Securityを使用している1つのプロジェクトに取り組んでおり、DBからユーザーをうまく認証します。
LDAP を使用してユーザーを認証し、既存の DB 認証も保持する必要があります。
また、次のような方法でユーザーが存在するかどうかを認証するための関数呼び出しが 1 つしかないため、Spring セキュリティを使用して標準の LDAP 認証方法を使用することはできません。
com.company.ldap.Authentication auth = new com.company.ldap.Authentication();
int status = auth.authenticate(userName, userPassword);
ステータスが 1 の場合、ユーザーは認証されます。それ以外の場合は認証されません。
したがって、このシナリオでは、別の URL "/j_spring_facebook_security_check" を作成しました (ここでは名前は facebook ですが、実際には LDAP 用です)。
私のapplicationContext-セキュリティファイル
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:http auto-config="true" use-expressions="true" access-denied-page="/accessDenied.jsp">
<security:form-login login-page="/index.jsp"
default-target-url="/jsp/home.jsp"
authentication-failure-handler-ref="authenticationFailureHandler" />
<security:intercept-url pattern="/jsp/listInBetweenPlaces.jsp"
access="permitAll" />
<security:intercept-url pattern="/jsp/home.jsp"
access="permitAll" />
<security:intercept-url pattern="/jsp/*"
access="isAuthenticated()" />
<security:logout logout-url="/j_spring_security_logout" logout-success-url="/index.jsp?logout=success"
invalidate-session="true" />
<security:custom-filter before="FORM_LOGIN_FILTER"
ref="facebookAuthenticationFilter" />
</security:http>
<bean id="facebookAuthenticationFilter" class="org.springframework.security.facebook.FacebookAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name = "authenticationSuccessHandler">
<bean class = "org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name = "defaultTargetUrl" value = "/jsp/home.jsp" />
<property name = "alwaysUseDefaultTargetUrl" value = "true" />
</bean>
</property>
<property name = "authenticationFailureHandler">
<bean class = "org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name = "defaultFailureUrl" value = "/fb/failure.jsp" />
</bean>
</property>
</bean>
<bean id="ldapAuthenticationProvider" class="org.springframework.security.facebook.FacebookAuthenticationProvider">
<property name="roles" value="ROLE_FACEBOOK_USER" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder hash="md5" />
</security:authentication-provider>
<security:authentication-provider ref="ldapAuthenticationProvider">
</security:authentication-provider>
</security:authentication-manager>
<bean id="customUserDetailsService" class="com.abc.carpool.authentication.CustomUserDetailsService">
</bean>
</beans>
FacebookAuthenticationFilter.java
public class FacebookAuthenticationFilter extends AbstractAuthenticationProcessingFilter implements ApplicationContextAware {
@Autowired
CarpoolService carpoolService=null;
public CarpoolService getCarpoolService() {
return carpoolService;
}
public void setCarpoolService(CarpoolService carpoolService) {
this.carpoolService = carpoolService;
}
public static final String DEFAULT_FILTER_PROCESS_URL = "/j_spring_facebook_security_check";
private ApplicationContext ctx;
protected FacebookAuthenticationFilter() {
super(DEFAULT_FILTER_PROCESS_URL);
}
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException,
IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String userName = request.getParameter("j_username");
String userPassword = request.getParameter("j_password");
System.out.println("Username and pswd is :"+userName + " " + userPassword);
System.out.println("SYS PATH :"+System.getenv("MC_ENV_PATH"));
User user = null;
try{
com.abc.ldap.Authentication auth = new com.abc.ldap.Authentication();
int status = auth.authenticate(userName, userPassword);
//int status=2;
if(status==1){
//CREATE NEW USER AND SAVE IN DB
}
}else{
throw new UsernameNotFoundException("Incorrect Email Id or Password.");
}
System.out.println("status is :"+status);
}catch (Exception e) {
System.out.println("Exception is "+e.getMessage());
e.printStackTrace();
return null;
}
System.out.println("FacebookAuthenticationFilter.attemptAuthentication() :"+userName + " " + userPassword);
UsernamePasswordAuthenticationToken upatToken = new UsernamePasswordAuthenticationToken(userName, userPassword);
AuthenticationManager authenticationManager = getAuthenticationManager();
Authentication auth = authenticationManager.authenticate(upatToken);
return auth;
}
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx;
}
}
FacebookAuthenticationProvider .java
public class FacebookAuthenticationProvider implements AuthenticationProvider {
private String[] roles;
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
System.out.println("FacebookAuthenticationProvider.authenticate()");
return authentication;
}
public boolean supports(Class<? extends Object> authentication) {
boolean supports = true;
return supports;
}
public void setRoles(String[] roles) {
this.roles = roles;
}
public String[] getRoles() {
return roles;
}
}
上記の場合、問題なく動作しています。コントロールはフィルター クラスに移動し、LDAP を使用してユーザーを検証します。ユーザーが存在する場合は、ユーザーの 1 つのコピーを自分の DB に保存し、通常のフローに進みたいと考えています。
実際に電話すると
Authentication auth = authenticationManager.authenticate(upatToken);
FacebookAuthenticationFilter、コントロールから、CustomUserDetailsService クラスに移動します。
私が必要としているのは、CustomUserDetailsService は DB 認証専用であり、制御をそこに移動させたくないということです。
いい方法でこれを達成する方法。