FormAuthenticationFilter是登陆已经认证的关键过滤器。
父类是AuthenticationFilter
由onPreHandle方法为起点,先判断当前用户是否已经登陆,然后当前账号是否是当前用户最后登陆的,如果不是,则拒绝,onAccessDenied,重定向到登陆界面
auth认证,
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
Subject subject=this.getSubject(request,response);
return subject.isAuthenticated() && isCurrentAccount(subject) ||onAccessDenied(request,response);
}
登陆走下面的方法,如果当前访问的路径是登陆路径,则执行登陆流程
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
if (this.isLoginRequest(request, response)){
return this.executeLogin(request, response);
}
return super.onPreHandle(request, response, mappedValue);
}
public boolean executeLogin(ServletRequest request, ServletResponse response) {
AuthenticationToken token=this.createToken(request,response);
if (token==null){
String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken must be created in order to execute a login attempt.";
throw new IllegalStateException(msg);
}else {
try {
Subject subject=this.getSubject(request,response);
// boolean existing = subject.getSession(false) != null;
// if (!existing){
// subject.getSession(true);
// }
subject.login(token);
return this.onLoginSuccess(token, subject, request, response);
} catch (AuthenticationException var5) {
return this.onLoginFailure(token, var5, request, response);
}
}
}
login方法:
Subject subject = this.securityManager.login(this, token);
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
AuthenticationInfo authenticationInfo;
try {
authenticationInfo=this.authenticate(token);
}catch (AuthenticationException e){
try {
this.onFailedLogin(token,e,subject);
}catch (Exception ez){
if(log.isInfoEnabled()) {
log.info("onFailedLogin method threw an exception. Logging and propagating original AuthenticationException.", ez);
}
}
throw e;
}
Subject loggedIn=this.createSubject(token,authenticationInfo,subject);
this.onSuccessfulLogin(token, authenticationInfo, loggedIn);
return loggedIn;
}
this.authenticate(token);会调用releam获取数据源的账号信息,也就是用户自定义的数据源(比如数据库)中的账号密码,与用户输入的账号密码对比。
@Override
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
this.assertRealmsConfigured();
Collection<Realm> realms = this.getRealms();
return realms.size() == 1?this.doSingleRealmAuthentication((Realm)realms.iterator().next(), authenticationToken):this.doMultiRealmAuthentication(realms, authenticationToken);
}
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token){
AuthenticationInfo info = this.doGetAuthenticationInfo(token);
if(info != null) {
this.assertCredentialsMatch(token, info);
}
return info;
}