実際のところ、Spring の名前空間ハンドラーは_formLoginFilter
、AuthenticationProcessingFilter の名前で Bean を内部的に定義しています ( BeanIdsの完全なリストについては、を参照してください)。この問題を回避する方法はいくつかあります (つまり、 DaoAuthenticationProvider から j_username 以外のものを使用して認証する、ヘッダーからユーザー名を取得するなど...)。
Spring AOPbean()
構文を使用してインターセプトするdoFilter()
_formLoginFilter
名前とインターセプトdoFilter
メソッドで Bean を探すポイントカットを定義します。( AuthenticationProcessingFilter.doFilter() method
) 条件付きで別のものに委任する
public class AuthenticationProcessingFilterAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationProcessingFilterAspect.class);
public Object intercept(ProceedingJoinPoint pjp) throws Throwable {
LOGGER.info("intercept------------------{}",pjp.toLongString());
//Delegate to customised method instead of default pjp.proceed()
return pjp.proceed();
}
}
設定
<beans:bean id="authFilterAspect" class="x.y.z.AuthenticationProcessingFilterAspect" />
<aop:config>
<aop:aspect ref="authFilterAspect">
<aop:around pointcut="bean(_formLoginFilter) && execution(* doFilter(..))" method="intercept"/>
</aop:aspect>
</aop:config>
CustomWebAuthenticationDetails を使用して認証を行う
カスタムフィールドに入力する CustomWebAuthenticationDetails を注入する AuthenticationProcessingFilter Bean の Bean ポストプロセッサーを定義します
public class AuthenticationProcessingFilterBeanPostProcessor implements
BeanPostProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationProcessingFilterBeanPostProcessor.class);
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if ("_formLoginFilter".equals(beanName) && bean instanceof AuthenticationProcessingFilter) {
AuthenticationProcessingFilter filter = (AuthenticationProcessingFilter) bean;
WebAuthenticationDetailsSource source = (WebAuthenticationDetailsSource) filter.getAuthenticationDetailsSource();
source.setClazz(CustomWebAuthenticationDetails.class);
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
@SuppressWarnings("serial")
public static class CustomWebAuthenticationDetails extends
WebAuthenticationDetails {
private String customAttribute;//customfield
public CustomWebAuthenticationDetails(HttpServletRequest request) {
super(request);
//Build custom attributes that could be used elsewhere (say in DaoAuthenticationProvider )
//with (CustomWebAuthenticationDetails)authentication.getDetails()
customAttribute = request.getHeader("username");
}
public boolean getCustomAttribute() {
return customAttribute;
}
}
}
設定
<beans:bean id="authFilterProcessor" class="x.y.z.AuthenticationProcessingFilterBeanPostProcessor" />
スレッド バインド リクエストを使用して実際の認証を行う (DaoAuthenticationProvider 内)
getHttpServletRequest() を使用してスレッドバインドされたリクエスト オブジェクトにアクセスし、request.getHeader("username") を使用してカスタム認証を行います。
public static HttpServletRequest getHttpServletRequest(){
return((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
}
また、リクエストが DispatcherServlet を介していない場合は、web.xml でこれを定義する必要があります。
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/j_spring_security_check</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/j_spring_security_logout</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
その顔のアプリケーションを使用する場合FacesContext.getCurrentInstance()
public static HttpServletRequest getHttpServletRequest(){
FacesContext context = FacesContext.getCurrentInstance();
return (HttpServletRequest) context.getExternalContext().getRequest();
}