我有一个带有用户名和密码的Spring登录表单,它指向/ myapp / j_spring_security_check。
我希望在Spring收到请求之前有人提交登录表单时拦截表单提交。
基本上,我希望能够查看用户输入以查看它是否符合某些要求。如果没有,应用程序将把用户带回登录表单。如果用户输入符合要求,则流程将转到Spring身份验证。
我该怎么做?以有效的方式?
谢谢!
答案 0 :(得分:3)
您可以使用常规Spring Security功能执行此操作。步骤是:
实施自定义WebAuthenticationDetailsSource
和WebAuthenticationDetails
。 WebAuthenticationDetails
将捕获您要验证的额外表单字段。
注意:在Spring 3.0中,您需要use a BeanPostProcessor to configure WebAuthenticationDetailsSource
进入UsernamePasswordAuthenticationFilter
。在Spring 3.1中,您可以直接在<form-login>
命名空间配置中执行此操作。
实施自定义AuthenticationProvider
并在authenticate()
中检查WebAuthenticationDetails
,如果验证失败则抛出AuthenticationException
。在您的登录页面中检查此例外。
或者,您可以创建一个Filter
进行验证并在Spring Security过滤器之前添加它。
答案 1 :(得分:1)
使用上面的答案作为指导,这是我创建的后处理器的一个工作示例,它允许您指定要向验证器提供的登录表单变量,以及一个示例自定义验证器,用于检查term_of_service复选框值。登录表单。
在Spring配置中:
<bean id="authFormDetailsPostProcessor" class="com.sefaira.authauth.AuthFormDetailsPostProcessor">
<property name="formVarNames" value="terms_of_service_accepted"/>
</bean>
AuthFormDetailsPostProcessor.java:
public class AuthFormDetailsPostProcessor implements BeanPostProcessor {
private String [] formVarNames;
public void setFormVarNames (String formVarNames) {
this.formVarNames = formVarNames.split (",");
}
public static class Details extends WebAuthenticationDetails {
private Map<String, String> map;
public Details (HttpServletRequest request, String [] parameters) {
super (request);
this.map = new HashMap<String, String>();
for (String parameter : parameters) {
this.map.put (parameter.trim(), request.getParameter (parameter.trim()));
}
}
public String get (String name) {
return map.get(name);
}
}
public Object postProcessAfterInitialization(Object bean, String name) {
if (bean instanceof UsernamePasswordAuthenticationFilter) {
((UsernamePasswordAuthenticationFilter)bean).setAuthenticationDetailsSource(
new AuthenticationDetailsSource() {
public Object buildDetails(Object context) {
if (formVarNames == null) {
throw new RuntimeException ("AuthFormDetailsPostProcessor bean requires a formVarNames property, specifying a comma-delimited list of form vars to provide in the details object.");
}
return new Details ((HttpServletRequest) context, formVarNames);
}
});
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String name) {
return bean;
}
}
这是使用它的自定义身份验证器:
public class AuthServiceAuthenticator implements AuthenticationProvider {
@Override
public Authentication authenticate (Authentication authentication) throws AuthenticationException {
String email = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
AuthFormDetailsPostProcessor.Details details = (AuthFormDetailsPostProcessor.Details) authentication.getDetails();
// see if they checked the terms_of_service checkbox
String termsOfServiceVar = details.get ("terms_of_service_accepted");
boolean termsOfServiceAccepted = (termsOfServiceVar != null && termsOfServiceVar.equals ("on"));
// ... do your custom authentication ...
return authentication; // or a new authentication object
}
@Override
public boolean supports(Class<? extends Object> authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
}