讓我們考慮一個每個人都熟悉的標準身份驗證方案。
1. 提示用戶使用用戶名和密碼登錄。
2. 系統(成功)驗證用戶名的密碼是否正確。
3. 獲取該用戶的上下文信息(他們的角色列表等)。
4. 為用戶建立安全上下文
5. 用戶繼續進行,可能執行一些可能受訪問控制機制保護的操作,該訪問控制機制針對當前安全上下文信息檢查操作所需的許可。
前三項構成了身份驗證過程,因此我們將了解這些內容是如何在Spring Security中進行的。
1. 獲取用戶名和密碼并將其組合到`UsernamePasswordAuthenticationToken`(`Authentication`接口的實例,我們之前看到)的實例中。
2. token傳遞給`AuthenticationManager`的實例以進行驗證。
3. `AuthenticationManager`在成功驗證后返回完全填充的`Authentication`實例。
4. 通過調用`SecurityContextHolder.getContext().setAuthentication(…)`建立安全上下文,傳入返回的身份驗證對象。
從那時起,用戶被認為是經過身份驗證的。 我們來看一些代碼作為例子。
~~~
import org.springframework.security.authentication.*;
import org.springframework.security.core.*;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
public class AuthenticationExample {
private static AuthenticationManager am = new SampleAuthenticationManager();
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) {
System.out.println("Please enter your username:");
String name = in.readLine();
System.out.println("Please enter your password:");
String password = in.readLine();
try {
Authentication request = new UsernamePasswordAuthenticationToken(name, password);
Authentication result = am.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
break;
} catch(AuthenticationException e) {
System.out.println("Authentication failed: " + e.getMessage());
}
}
System.out.println("Successfully authenticated. Security context contains: " +
SecurityContextHolder.getContext().getAuthentication());
}
}
class SampleAuthenticationManager implements AuthenticationManager {
static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
static {
AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
}
public Authentication authenticate(Authentication auth) throws AuthenticationException {
if (auth.getName().equals(auth.getCredentials())) {
return new UsernamePasswordAuthenticationToken(auth.getName(),
auth.getCredentials(), AUTHORITIES);
}
throw new BadCredentialsException("Bad Credentials");
}
}
~~~
在這里,我們編寫了一個小程序,要求用戶輸入用戶名和密碼并執行上述順序。 我們在此實現的AuthenticationManager將驗證用戶名和密碼相同的任何用戶。 它為每個用戶分配一個角色。 上面的輸出將是這樣的:
~~~
Please enter your username:
bob
Please enter your password:
password
Authentication failed: Bad Credentials
Please enter your username:
bob
Please enter your password:
bob
Successfully authenticated. Security context contains: \
org.springframework.security.authentication.UsernamePasswordAuthenticationToken@441d0230: \
Principal: bob; Password: [PROTECTED]; \
Authenticated: true; Details: null; \
Granted Authorities: ROLE_USER
~~~
請注意,您通常不需要編寫任何類似的代碼。 該過程通常在內部進行,例如在Web身份驗證過濾器中。 我們剛剛在這里包含了代碼,以表明在Spring Security中實際構成身份驗證的問題有一個非常簡單的答案。 當`SecurityContextHolder`包含完全填充的`Authentication`對象時,用戶已進行了身份驗證。
- 架構
- 9.技術概述
- 9.1 運行環境
- 9.2 核心組件
- 9.2.1 SecurityContextHolder, SecurityContext and Authentication Objects
- 9.2.2 The UserDetailsService
- 9.2.3 GrantedAuthority
- 9.2.4 總結
- 9.3 驗證
- 9.3.1 在Spring Security中驗證是什么
- 9.3.2 直接設置SecurityContextHolder內容
- 9.4 web應用中的驗證
- 9.4.1 ExceptionTranslationFilter
- 9.4.2 AuthenticationEntryPoint
- 9.4.3 驗證機制
- 9.4.4 在請求之間存儲SecurityContext
- 9.5 Spring Security中的訪問控制(授權)
- 9.5.1 Security and AOP Advice
- 9.5.2 Secure Objects and the AbstractSecurityInterceptor
- 什么是配置屬性
- RunAsManager
- AfterInvocationManager
- 擴展安全對象模型
- 9.6 本地化
- 10 核心服務
- 10.1 The AuthenticationManager, ProviderManager and AuthenticationProvider
- 10.1.1 成功驗證時擦除憑據
- 10.1.2 DaoAuthenticationProvider
- 10.2 UserDetailsService實現
- 10.2.1 In-Memory Authentication
- 10.2.2 JdbcDaoImpl
- Authority Groups
- 10.3 Password Encoding
- 10.3.1 密碼發展史
- 10.3.2 DelegatingPasswordEncoder
- 密碼存儲格式
- 密碼編碼
- 密碼比對
- 入門體驗
- 排除故障
- 10.3.3 BCryptPasswordEncoder
- 10.3.4 Pbkdf2PasswordEncoder
- 10.3.5 SCryptPasswordEncoder
- 10.3.6 其他PasswordEncoders
- 10.4 Jackson的支持
- 11 測試方法安全
- 12 集成spring mvc測試
- 13 webflux支持
- 14 安全過濾器鏈
- 14.1 DelegatingFilterProxy
- 14.2 FilterChainProxy
- 14.2.1 繞過過濾鏈
- 14.3 過濾器順序
- 14.4 匹配請求和http防火墻
- 14.5 與其他基于過濾器的框架一起使用
- 14.6 Advanced Namespace Configuration
- 15. 核心的安全過濾器
- 15.1 FilterSecurityInterceptor
- 15.2 ExceptionTranslationFilter
- 15.3 SecurityContextPersistenceFilter
- 15.4 UsernamePasswordAuthenticationFilter