根据感悟1过滤器的流程,假设此时jsessionid已经保存在浏览器当中了。一路执行会来到FormAuthenticationFilter的onAccessDenied()方法。如下图:
该onAccessDenied()方法内部有个executeLogin()方法,跟踪进去。如图:
我们来看看onLoginSuccess()和onLoginFailure()方法,如图:
现在稍微打断一下。我们来分析各个过滤器的大体作用:
AccessControlFilter:控制获取资源和重定向到登陆页面在用户没有认证的情况下的那些过滤器的超类。所以需要注意“控制”和“重定向”这两个词。大致需要对loginUrl的一些操作,比如saveRequestAndRedirectToLogin()、saveRequest()、redirectToLogin(),就是保存request请求,并重定向到登陆页面。注意保存request,怎么保存?见下面。
我们来看看saveRequest方法,Convenience method merely delegates to WebUtils.saveRequest(request)
to save the request state for reuse later. This is mostly used to retain user request state when a redirect is issued to return the user to their originally requested url/resource.,就是保存当前请求状态,以后会用到。如下图:
WebUtils.saveRequest()方法:如下图
由此我们知道,saveRequest是把当前的request保存到session当中。如果session为null的话,就去创建session。
AccessControlFilter还有一个关键词就是“控制”:onPreHandle()、isAccessAllowed()、onAccessDenied()。需要特定的操作,子类需要重写它。
AdviceFilter:A Servlet Filter that enables AOP-style "around" advice for a ServletRequest via preHandle
, postHandle
, and afterCompletion
hooks.环绕通知过滤器,专门处理前置与后置的工作。比如后置工作就是cleanup()方法,前置的具体的工作由子类重写实现具体的工作。
AuthenticationFilter:Base class for all Filters that require the current user to be authenticated. This class encapsulates the logic of checking whether a user is already authenticated in the system while subclasses are required to perform specific logic for unauthenticated requests.大概的意思是:该类是所有需要当前用户进行认证的过滤器的基类。该类封装了验证当前用户是否验证过在本系统的一些处理逻辑。同时要求子类实现在没有认证过的请求的一些特殊的处理逻辑。
我们可以推想一下,在验证过程中,如果验证成功需要干嘛?需要重定向到successUrl,对吧。如果验证成功需要干嘛?当然保存保存当前请求,然后重定向到loginUrl。但是:AuthenticationFilter主要是该用户验证成功过的一些处理逻辑。你看,验证成功,大致需要successUrl的信息和issueSuccessRedirect()方法,这个类也主要就是这些信息。
AuthenticatingFilter:前面我们知道,一个是AuthenticationFilter,一个是AuthenticatingFilter。带"ing"的AuthenticatingFilter表示执行验证登陆的具体操作,而父类AuthenticationFilter前面也说过只负责successUrl和重定向successUrl的操作,而该类就是真正的executeLogin()。
FormAuthenticationFilter:
Requires the requesting user to be authenticated for the request to continue, and if they are not, forces the user to login via by redirecting them to the loginUrl you configure.
This filter constructs a UsernamePasswordToken with the values found in username
, password
, and rememberMe
request parameters. It then calls Subject.login(usernamePasswordToken) , effectively automatically performing a login attempt. Note that the login attempt will only occur when the isLoginSubmission(request,response) is true
, which by default occurs when the request is for the loginUrl
and is a POST request.
If the login attempt fails, the resulting AuthenticationException
fully qualified class name will be set as a request attribute under the failureKeyAttribute key. This FQCN can be used as an i18n key or lookup mechanism to explain to the user why their login attempt failed (e.g. no account, incorrect password, etc).
If you would prefer to handle the authentication validation and login in your own code, consider using the PassThruAuthenticationFilter
instead, which allows requests to the loginUrl
to pass through to your application's code directly.
FormAuthenticationFilter顾名思义就是表单认证过滤器,首先就是要一个post方式提交的表单,认证用户的时候,需要username和password对吧,否则怎么认证。认证成功则调用超类(AuthenticationFilter)重定向到successUrl(默认successUrl的路径是”/“),如果认证失败则继续执行前往登陆页面,并给request添加一个认证失败的参数”shiroLoginFailure“。