Spring Security(一):官網嚮導翻譯
原文出自 https://spring.io/guides/topicals/spring-security-architecture
Spring Security Architecture
This guide is a primer for Spring Security, offering insight into the design and basic building blocks of the framework. We only cover the very basics of application security but in doing so we can clear up some of the confusion experienced by developers using Spring Security. To do this we take a look at the way security is applied in web applications using filters and more generally using method annotations. Use this guide when you need to understand at a high level how a secure application works, and how it can be customized, or if you just need to learn how to think about application security. 本指南是Spring Security的入門讀物,提供對框架設計和基本構建塊的深入瞭解。我們只介紹應用程式安全性的基礎知識,但這樣做可以清除開發人員使用Spring Security時遇到的一些困惑。為此,我們將介紹使用過濾器在Web應用程式中應用安全性的方式,更常見的是使用方法註釋。當您需要從高層次瞭解安全應用程式如何工作,如何自定義,或者您只需要學習如何考慮應用程式安全性時,請使用本指南。 This guide is not intended as a manual or recipe for solving more than the most basic problems (there are other sources for those), but it could be useful for beginners and experts alike. Spring Boot is also referred to a lot because it provides some default behaviour for a secure application and it can be useful to understand how that fits in with the overall architecture. All of the principles apply equally well to applications that do not use Spring Boot. 本指南不是作為解決超過最基本問題的手冊或配方(還有其他來源),但它對初學者和專家都很有用。 Spring Boot也引用了很多,因為它為安全應用程式提供了一些預設行為,瞭解它如何適應整體架構非常有用。所有原則同樣適用於不使用Spring Boot的應用程式。Authentication and Access Control
Application security boils down to two more or less independent problems: authentication (who are you?) and authorization (what are you allowed to do?). Sometimes people say "access control" instead of "authorization" which can get confusing, but it can be helpful to think of it that way because "authorization" is overloaded in other places. Spring Security has an architecture that is designed to separate authentication from authorization, and has strategies and extension points for both.
Authentication
The main strategy interface for authentication is AuthenticationManager
which only has one method:
身份驗證的主要策略介面是 AuthenticationManager ,它只有一個方法:
public interface AuthenticationManager { Authentication authenticate(Authentication authentication) throws AuthenticationException; }
An AuthenticationManager
can do one of 3 things in its authenticate()
method:
AuthenticationManager可以在authenticate()方法中執行以下三種操作之一:
1、return an Authentication
(normally with authenticated=true
) if it can verify that the input represents a valid principal.
1、如果它可以驗證輸入是否代表有效的主體,則返回身份驗證(通常使用authenticated = true)。
2、throw anAuthenticationException
if it believes that the input represents an invalid principal.
2、如果它認為輸入表示無效的主體,則丟擲AuthenticationException。
3、return
null
if it can’t decide.
3、如果無法決定,則返回null。
AuthenticationException
is a runtime exception. It is usually handled by an application in a generic way, depending on the style or purpose of the application. In other words user code is not normally expected to catch and handle it. For example, a web UI will render a page that says that the authentication failed, and a backend HTTP service will send a 401 response, with or without a
WWW-Authenticate
header depending on the context.
AuthenticationException是執行時異常。它通常由應用程式以通用方式處理,具體取決於應用程式的樣式或目的。換句話說,通常不希望使用者程式碼捕獲並處理它。例如,Web UI將呈現一個頁面,表明身份驗證失敗,後端HTTP服務將傳送401響應,具有或不具有WWW-Authenticate標頭,具體取決於上下文。
The most commonly used implementation of
AuthenticationManager
is
ProviderManager
, which delegates to a chain of
AuthenticationProvider
instances. An
AuthenticationProvider
is a bit like an
AuthenticationManager
but it has an extra method to allow the caller to query if it supports a given
Authentication
type:
AuthenticationManager最常用的實現是
ProviderManager,它委託一系列
AuthenticationProvider例項。
AuthenticationProvider有點像AuthenticationManager,但它有一個額外的方法允許呼叫者查詢它是否支援給定的身份驗證型別:
public interface AuthenticationProvider { Authentication authenticate(Authentication authentication) throws AuthenticationException; boolean supports(Class<?> authentication); }
The Class<?>
argument in the supports()
method is really Class<? extends Authentication>
(it will only ever be asked if it supports something that will be passed into the authenticate()
method). A ProviderManager
can support multiple different authentication mechanisms in the same application by delegating to a chain of AuthenticationProviders
. If a ProviderManager
doesn’t recognise a particular Authentication
instance type it will be skipped.
supports()方法中的Class <?>引數實際上是Class <?擴充套件身份驗證>(只會詢問它是否支援將傳遞給authenticate()方法的內容)。通過委派給AuthenticationProviders鏈,ProviderManager可以在同一個應用程式中支援多種不同的身份驗證機制。如果ProviderManager無法識別特定的身份驗證例項型別,則會跳過它。
A ProviderManager
has an optional parent, which it can consult if all providers return null
. If the parent is not available then a null
Authentication
results in an AuthenticationException
.
Sometimes an application has logical groups of protected resources (e.g. all web resources that match a path pattern /api/**
), and each group can have its own dedicated AuthenticationManager
. Often, each of those is a ProviderManager
, and they share a parent. The parent is then a kind of "global" resource, acting as a fallback for all providers.
Figure 1. An AuthenticationManager
hierarchy using ProviderManager
Customizing Authentication Managers(自定義身份驗證管理器)
Spring Security provides some configuration helpers to quickly get common authentication manager features set up in your application. The most commonly used helper is the AuthenticationManagerBuilder
which is great for setting up in-memory, JDBC or LDAP user details, or for adding a custom UserDetailsService
. Here’s an example of an application configuring the global (parent)
@Configuration public class ApplicationSecurity extends WebSecurityConfigurerAdapter { ... // web stuff here @Autowired public initialize(AuthenticationManagerBuilder builder, DataSource dataSource) { builder.jdbcAuthentication().dataSource(dataSource).withUser("dave") .password("secret").roles("USER"); } }
This example relates to a web application, but the usage of AuthenticationManagerBuilder
is more widely applicable (see below for more detail on how web application security is implemented). Note that the AuthenticationManagerBuilder
is @Autowired
into a method in a @Bean
- that is what makes it build the global (parent) AuthenticationManager
. In contrast if we had done it this way:
@Configuration public class ApplicationSecurity extends WebSecurityConfigurerAdapter { @Autowired DataSource dataSource; ... // web stuff here @Override public configure(AuthenticationManagerBuilder builder) { builder.jdbcAuthentication().dataSource(dataSource).withUser("dave") .password("secret").roles("USER"); } }
(using an @Override
of a method in the configurer) then the AuthenticationManagerBuilder
is only used to build a "local" AuthenticationManager
, which is a child of the global one. In a Spring Boot application you can @Autowired
the global one into another bean, but you can’t do that with the local one unless you explicitly expose it yourself.
AuthenticationManager
(with just one user) unless you pre-empt it by providing your own bean of type
AuthenticationManager
. The default is secure enough on its own for you not to have to worry about it much, unless you actively need a custom global
AuthenticationManager
. If you do any configuration that builds an
AuthenticationManager
you can often do it locally to the resources that you are protecting and not worry about the global default.
Spring Boot提供了一個預設的全域性AuthenticationManager(只有一個使用者),除非您通過提供自己的AuthenticationManager型別的bean來搶佔它。除非您主動需要自定義全域性AuthenticationManager,否則預設設定足夠安全,您不必擔心它。如果您執行構建AuthenticationManager的任何配置,您通常可以在本地執行您正在保護的資源,而不必擔心全域性預設值。
Authorization or Access Control(授權或訪問控制)