Spring Security web 应用程序的认证过程

一:认证入口:
AbstractAuthenticationProcessingFilter 用于拦截认证请求,它是基于浏览器和 HTTP 认证请求的处理器,可以理解为它就是 Spring Security 认证流程的入口。
整个认证流程如下:
AbstractAuthenticationProcessingFilter 收集用于认证的用户身份信息(通常是用户名和密码),并基于这些信息构造一个 Authentication 请求对象,AbstractAuthenticationProcessingFilter 只是一个抽象类,查看 Spring Security API 文档 可以看到 Spring Security 提供了几个实现类:
CasAuthenticationFilter
OAuth2LoginAuthenticationFilter
OpenIDAuthenticationFilter
UsernamePasswordAuthenticationFilter
最常使用的应该是 UsernamePasswordAuthenticationFilter,其它类都应用于特定的场景。
AbstractAuthenticationProcessingFilter 类将构造的 Authentication 请求对象呈现给 AuthenticationManagerAbstractAuthenticationProcessingFilter 类有以下方法设置和获取 AuthenticationManager

二:Consider a typical web application’s authentication process:
典型的 web 应用程序认证步骤

  1. You visit the home page, and click on a link.
  2. A request goes to the server, and the server decides that you’ve asked for a protected resource.
  3. As you’re not presently authenticated, the server sends back a response indicating that you must authenticate. The response will either be an HTTP response code, or a redirect to a particular web page.
  4. Depending on the authentication mechanism, your browser will either redirect to the specific web page so that you can fill out the form, or the browser will somehow retrieve your identity (via a BASIC authentication dialogue box, a cookie, a X.509 certificate etc.).
  5. The browser will send back a response to the server. This will either be an HTTP POST containing the contents of the form that you filled out, or an HTTP header containing your authentication details.
  6. Next the server will decide whether or not the presented credentials are valid. If they’re valid, the next step will happen. If they’re invalid, usually your browser will be asked to try again (so you return to step two above).
  7. The original request that you made to cause the authentication process will be retried. Hopefully you’ve authenticated with sufficient granted authorities to access the protected resource. If you have sufficient access, the request will be successful. Otherwise, you’ll receive back an HTTP error code 403, which means "forbidden".

Spring Security has distinct classes responsible for most of the steps described above. The main participants (in the order that they are used) are the ExceptionTranslationFilter, an AuthenticationEntryPoint and an "authentication mechanism", which is responsible for calling the AuthenticationManager which we saw in the previous section.

9.4.1 ExceptionTranslationFilter

ExceptionTranslationFilter is a Spring Security filter that has responsibility for detecting any Spring Security exceptions that are thrown. Such exceptions will generally be thrown by an AbstractSecurityInterceptor, which is the main provider of authorization services. We will discuss AbstractSecurityInterceptor in the next section, but for now we just need to know that it produces Java exceptions and knows nothing about HTTP or how to go about authenticating a principal.

ExceptionTranslationFilter 负责响应403(第七步)或者启动AuthenticationEntryPoint(第三步)
Instead the ExceptionTranslationFilter offers this service, with specific responsibility for either returning error code 403 (if the principal has been authenticated and therefore simply lacks sufficient access - as per step seven above), or launching an AuthenticationEntryPoint (if the principal has not been authenticated and therefore we need to go commence step three).

9.4.2 AuthenticationEntryPoint

认证点负责第三步
The AuthenticationEntryPoint is responsible for step three in the above list. As you can imagine, each web application will have a default authentication strategy (well, this can be configured like nearly everything else in Spring Security, but let’s keep it simple for now). Each major authentication system will have its own AuthenticationEntryPoint implementation, which typically performs one of the actions described in step 3.

9.4.3 Authentication Mechanism 认证机制

Once your browser submits your authentication credentials (either as an HTTP form post or HTTP header) there needs to be something on the server that "collects" these authentication details.
一旦提交了认证凭证,服务端需要有一些东西来收集这些认证信息

By now we’re at step six in the above list. In Spring Security we have a special name for the function of collecting authentication details from a user agent (usually a web browser), referring to it as the "authentication mechanism".

我们正在上面的列表中的第六步。在Spring Security中,我们为从用户代理(通常是Web浏览器)收集验证信息的功能提供了一个特殊的名称,称之为“验证机制”

Examples are form-base login and Basic authentication. Once the authentication details have been collected from the user agent, an Authentication "request" object is built and then presented to the AuthenticationManager.

示例是基于表单的登录和基本身份验证。一旦从用户代理收集了认证详细信息,就构建一个认证“请求”(Authentication "request")对象,然后将其呈现给AuthenticationManager。

After the authentication mechanism receives back the fully-populated Authentication object, it will deem the request valid, put the Authentication into the SecurityContextHolder, and cause the original request to be retried (step seven above).

认证机制接收到完全填充的认证对象 Authentication实例(包括权限信息,身份信息,细节信息,但密码通常会被移除)后,认为请求有效,将认证放入SecurityContextHolder,并导致原始请求重试(上面的第七步)

If, on the other hand, the AuthenticationManager rejected the request, the authentication mechanism will ask the user agent to retry (step two above).

另一方面,如果AuthenticationManager拒绝了请求,认证机制将要求用户代理重试(上面的第二步)

Figure 9.1. Security interceptors and the "secure object" model

Extending the Secure Object Model
Only developers contemplating an entirely new way of intercepting and authorizing requests would need to use secure objects directly.

只有开发人员想要采用全新的截取和授权请求的方式,才需要直接使用安全对象

For example, it would be possible to build a new secure object to secure calls to a messaging system. Anything that requires security and also provides a way of intercepting a call (like the AOP around advice semantics) is capable of being made into a secure object.

Having said that, most Spring applications will simply use the three currently supported secure object types (AOP Alliance MethodInvocation, AspectJ JoinPoint and web request FilterInvocation) with complete transparency.

话虽如此,大多数Spring应用程序将完全透明地使用目前支持的三种安全对象类型

AbstractSecurityInterceptor 的作用说明:

Abstract class that implements security interception for secure objects.
实现了对安全对象安全拦截的抽象类
The AbstractSecurityInterceptor will ensure the proper startup configuration of the security interceptor. It will also implement the proper handling of secure object invocations, namely:
AbstractSecurityInterceptor 将确保安全拦截器的正确启动配置,它还将实现对安全对象调用的正确处理,即

  1. Obtain the Authentication object from the SecurityContextHolder.
  2. Determine if the request relates to a secured or public invocation by looking up the secure object request against the SecurityMetadataSource.
  3. For an invocation that is secured (there is a list of ConfigAttributes for the secure object invocation):
    a. If either the Authentication.isAuthenticated() returns false, or the alwaysReauthenticate is true, authenticate the request against the configured AuthenticationManager. When authenticated, replace the Authentication object on the SecurityContextHolder with the returned value.
    b. Authorize the request against the configured AccessDecisionManager.
    c. Perform any run-as replacement via the configured RunAsManager.
    d. Pass control back to the concrete subclass, which will actually proceed with executing the object. A InterceptorStatusToken is returned so that after the subclass has finished proceeding with execution of the object, its finally clause can ensure the AbstractSecurityInterceptor is re-called and tidies up correctly using finallyInvocation(InterceptorStatusToken).
    e. The concrete subclass will re-call the AbstractSecurityInterceptor via the afterInvocation(InterceptorStatusToken, Object) method.
    f. If the RunAsManager replaced the Authentication object, return the SecurityContextHolder to the object that existed after the call to AuthenticationManager.
    g. If an AfterInvocationManager is defined, invoke the invocation manager and allow it to replace the object due to be returned to the caller.
  4. For an invocation that is public (there are no ConfigAttributes for the secure object invocation):
    a. As described above, the concrete subclass will be returned an InterceptorStatusToken which is subsequently re-presented to the AbstractSecurityInterceptor after the secure object has been executed. The AbstractSecurityInterceptor will take no further action when its afterInvocation(InterceptorStatusToken, Object) is called.
  5. Control again returns to the concrete subclass, along with the Object that should be returned to the caller. The subclass will then return that result or exception to the original caller
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容