post:完成Spring Security基础文章。

This commit is contained in:
徐涛
2021-07-29 22:03:08 +08:00
parent fffdd03333
commit c30c88dfbd
6 changed files with 491 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
@startuml
skinparam Shadowing false
skinparam class {
BackgroundColor White
}
hide empty members
interface AuthenticationManager {
+ Authentication authenticate(Authentication authentication)
}
class ProviderManager {
- AuthenticationEventPublisher eventPublisher
- List<AuthenticationProvider> providers
- MessageSourceAccessor messages
- AuthenticationManager parent
- boolean eraseCredentialsAfterAuthentication
+ ProviderManager(AuthenticationProvider... providers)
+ ProviderManager(List<AuthenticationProvider> providers)
+ ProviderManager(List<AuthenticationProvider> providers, AuthenticationManager parent)
+ void afterPropertiesSet()
- void checkState()
- void copyDetails(Authentication source, Authentication dest)
+ List<AuthenticationProvider> getProviders()
+ void setMessageSource(MessageSource messageSource)
+ void setAuthenticationEventPublisher(AuthenticationEventPublisher eventPublisher)
+ void setEraeseCredentialsAfterAuthentication(boolean eraseSecretData)
+ boolean isEraseCredentialsAfterAuthentication()
}
class NullEventPublisher
interface AuthenticationEventPublisher {
+ void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication)
+ void publishAuthenticationSuccess(Authentication authentication)
}
interface AuthenticationProvider {
+ Authentication authenticate(Authentication authentication)
+ boolean supports(Class<?> authentication)
}
abstract AbstractUserDetailsAuthenticationProvider {
# MessageSourceAccessor messages
- UserCache userCache
- boolean forcePrincipalAsString
- boolean hideUserNotFoundException
- UserDetailsChecker preAuthenticationChecks
- UserDetailsChecker postAuthenticationChecks
- GrantedAuthoritiesMapper authoritiesMapper
#{abstract} void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
+ void afterPropertiesSet()
- String determineUsername(Authentication authentication)
# Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user)
# void doAfterPropertiesSet()
#{abstract} UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
}
interface UserDetailsChecker {
+ void check(UserDetails toCheck)
}
class DefaultPreAuthenticationChecks
class DefaultPostAuthenticationChecks
interface UserCache {
+ UserDetails getUserFromCache(String username)
+ void putUserInCache(UserDetails user)
+ void removeUserFromCache(String username)
}
class UserDetails {
+ Collection<? extends GrantedAuthority> getAuthorities()
+ String getPassword()
+ String getUsername()
+ boolean isAccountNonExpired()
+ boolean isAccountNonLocked()
+ boolean isCredentialsNonExpired()
+ boolean isEnabled()
}
interface GrantedAuthoritiesMapper {
+ Collection<? extends GrantedAuthority> mapAuthorities(Collection<? extends GrantedAuthority> authorities)
}
interface GrantedAuthority {
+ String getAuthority()
}
class SimpleGrantedAuthority {
- String role
}
class SpringCacheBasedUserCache
class UsernamePasswordAuthenticationToken {
- Object principal
- Object credentials
}
abstract AbstractAuthenticationToken {
- Collection<GrantedAuthority> authorities
- Object details
- boolean authenticated
}
interface Authentication
interface CredentialsContainer {
+ void eraseCredentials()
}
AuthenticationManager <|.. ProviderManager
ProviderManager +-- NullEventPublisher
NullEventPublisher ..|> AuthenticationEventPublisher
AuthenticationProvider "1..*" --* "1" ProviderManager
AbstractUserDetailsAuthenticationProvider ..|> AuthenticationProvider
DefaultPreAuthenticationChecks --+ AbstractUserDetailsAuthenticationProvider
DefaultPostAuthenticationChecks --+ AbstractUserDetailsAuthenticationProvider
UserDetailsChecker <|.. DefaultPreAuthenticationChecks
UserDetailsChecker <|.. DefaultPostAuthenticationChecks
UserCache --* AbstractUserDetailsAuthenticationProvider
UserDetails --* AbstractUserDetailsAuthenticationProvider
UserDetails --* UserDetailsChecker
UserDetails --* UserCache
AbstractUserDetailsAuthenticationProvider *--- GrantedAuthoritiesMapper
GrantedAuthoritiesMapper *-- GrantedAuthority
GrantedAuthority <|.. SimpleGrantedAuthority
UserCache <|.. SpringCacheBasedUserCache
UsernamePasswordAuthenticationToken --* AbstractUserDetailsAuthenticationProvider
AbstractAuthenticationToken <|-- UsernamePasswordAuthenticationToken
Authentication <|.. AbstractAuthenticationToken
CredentialsContainer <|.. AbstractAuthenticationToken
@enduml

View File

@@ -0,0 +1,90 @@
@startuml
skinparam Shadowing false
skinparam class {
BackgroundColor White
}
hide empty members
package org.springframework.security.core {
package context {
class SecurityContextHolder {
-{static} SecurityContextHolderStrategy strategy
-{static} int initilizeCount
-{static} void initilize()
+{static} void clearContext()
+{static} SecurityContext getContext()
+{static} int getInitilizeCount()
+{static} void setContext(SecurityContext context)
+{static} void setStrategyName(String strategyName)
+{static} SecurityContextHolderStrategy getContextHolderStrategy()
+{static} SecurityContext createEmptyContext()
}
interface SecurityContextHolderStrategy {
+ void clearContext()
+ SecurityContext getContext()
+ void setContext(SecurityContext context)
+ SecurityContext createEmptyContext()
}
class ThreadLocalSecurityContextHolderStrategy {
-{static} ThreadLocal<SecurityContext> contextHolder
}
class GlobalSecurityContextHolderStrategy {
-{static} SecurityContext contextHolder
}
class InheritableThreadLocalSecurityContextHolderStrategy {
-{static} ThreadLocal<SecurityContext> contextHolder
}
class ReactiveSecurityContextHolder {
+{static} Mono<SecurityContext> getContext()
-{static} boolean hasSecurityContext(Context context)
-{static} Mono<SecurityContext> getSecurityContext(Context context)
+{static} Function<Context, Context> clearContext()
+{static} Context withSecurityContext(Mono<? extends SecurityContext> securityContext)
+{static} Context withAuthentication(Authentication authntication)
}
class SecurityContext {
+ Authentication getAuthentication()
+ void setAuthentication(Authentication authentication)
}
}
interface Authentication {
+ Collection<? extends GrantedAuthority> getAuthorities()
+ Object getCredentials()
+ Object getDetails()
+ Object getPrincipal()
+ boolean isAuthticated()
+ setAuthenticated(boolean isAuthenticated)
}
interface GrantedAuthority {
+ String getAuthority()
}
}
package java.security {
interface Principal {
+ String getName()
+ boolean implies(Subject subject)
}
}
SecurityContextHolderStrategy --* SecurityContextHolder
ThreadLocalSecurityContextHolderStrategy ..|> SecurityContextHolderStrategy
GlobalSecurityContextHolderStrategy ..|> SecurityContextHolderStrategy
InheritableThreadLocalSecurityContextHolderStrategy ...|> SecurityContextHolderStrategy
SecurityContext --* SecurityContextHolderStrategy
SecurityContext -* ReactiveSecurityContextHolder
SecurityContext --* ThreadLocalSecurityContextHolderStrategy
SecurityContext --* InheritableThreadLocalSecurityContextHolderStrategy
SecurityContext --* GlobalSecurityContextHolderStrategy
Authentication --* SecurityContext
GrantedAuthority -* Authentication
Authentication -|> Principal
@enduml

View File

@@ -0,0 +1,71 @@
@startuml
skinparam Shadowing false
skinparam class {
BackgroundColor White
}
hide empty members
abstract AbstractUserDetailsAuthenticationProvider
class UserDetails
class DaoAuthenticationProvider {
- PasswordEncoder passwordEncoder
- String userNotFoundEncodedPassword
- UserDetailsService userDetailsService
- UserDetailsPasswordService userDetailsPasswordService
- void prepareTimingAttackProtection()
- void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken authentication)
}
interface UserDetailsService {
+ UserDetails loadUserByUsername(String username)
}
interface UserDetailsPasswordService {
+ UserDetails update(UserDetails user, String password)
}
interface PasswordEncoder {
+ String encode(CharSequence rawPassword)
+ boolean matches(CharSequence rawPassword, String encodedPassword)
+ boolean upgradeEncoding(String rawPassword)
}
class UsernamePasswordAuthenticationToken
abstract AbstractPasswordEncoder {
# byte[] encode(CharSequence rawPassword, byte[] salt)
# byte[] encodeAndConcatenate(CharSequence rawPassword, byte[] salt)
# {static} boolean matches(byte[] expected, byte[] actual)
}
class DelegatingPasswordEncoder {
- {static} String PREFIX
- {static} String SUFFIX
- String idForEncode
- PasswordEncoder passwordEncoderForEncode
- Map<String, PasswordEncoder> idToPasswordEncoder
- PasswordEncoder defaultPasswordEncoderForMatches
+ DelegatingPasswordEncoder(String idForEncode, Map<String, PasswordEncoder> idToPasswordEncoder)
+ void setDefaultPasswordEncoderForMatches(PasswordEncoder defaultPasswordEncoderForMatches)
- String extractId(String prefixEncodedPassword)
- String extractEncodedPassword(String prefixEncodedPassword)
}
class UnmappedIdPasswordEncoder
class BCryptPasswordEncoder
class Pbkdf2PasswordEncoder
DaoAuthenticationProvider --|> AbstractUserDetailsAuthenticationProvider
UserDetailsService --* DaoAuthenticationProvider
UserDetailsPasswordService --* DaoAuthenticationProvider
UsernamePasswordAuthenticationToken --* DaoAuthenticationProvider
PasswordEncoder ---* DaoAuthenticationProvider
UserDetails --* UserDetailsService
UserDetails --* UserDetailsPasswordService
AbstractPasswordEncoder ..|> PasswordEncoder
DelegatingPasswordEncoder ..|> PasswordEncoder
DelegatingPasswordEncoder +-- UnmappedIdPasswordEncoder
UnmappedIdPasswordEncoder ..|> PasswordEncoder
BCryptPasswordEncoder ..|> PasswordEncoder
Pbkdf2PasswordEncoder ..|> PasswordEncoder
@enduml

View File

@@ -0,0 +1,34 @@
@startdot spring-security-servlet-flow
digraph servlet {
rankdir=TB
edge [color="#A60738"]
node [color="#A60738"]
client [shape=box, label="客户端"]
servlet [shape=box, label="Servlet"]
tokenStorage [shape=box, label="令牌缓存"]
{ rank=same; tokenStorage; RememberMeServices }
client -> FilterChain [label="原始请求"]
FilterChain -> SecurityFilterChain [label="经过中转的请求"]
SecurityFilterChain -> UsernamePasswordAuthenticationProviderFilter [label="携带有用户名和密码的请求"]
UsernamePasswordAuthenticationProviderFilter -> AuthenticationManager [label="UsernamePasswordAuthenticationToken"]
AuthenticationManager -> SecurityContext [label="认证后的Authentication"]
SecurityFilterChain -> BearerTokenAuthenticationFilter [label="携带有Authorization头的请求"]
BearerTokenAuthenticationFilter -> AuthenticationManager [label="BearerTokenAuthenticationToken"]
AuthenticationManager -> DaoAuthenticationProvider [label="UsernamePasswordAuthenticationToken"]
DaoAuthenticationProvider -> UserDetailsService [label="UserDetails"]
UserDetailsService -> DaoAuthenticationProvider [label="认证后的UserDetails"]
DaoAuthenticationProvider -> PasswordEncoder [label="用户认证密码"]
PasswordEncoder -> DaoAuthenticationProvider [label="经过加密的密码"]
DaoAuthenticationProvider -> SecurityContext [label="认证后的Authentication"]
SecurityFilterChain -> RememberMeAuthenticationFilter [label="携带RememberMe认证的请求"]
RememberMeAuthenticationFilter -> RememberMeServices [label="RememberMeAuthenticationToken"]
RememberMeServices -> tokenStorage [label="认证令牌信息"]
RememberMeServices -> SecurityContext [label="认证后的Authentication"]
SecurityFilterChain -> AnonymousAuthenticationFilter [label="不携带任何认证信息请求"]
AnonymousAuthenticationFilter -> SecurityContext [label="匿名Authentication"]
SecurityContext -> servlet [label="已经加入认证信息的请求"]
}
@enddot

View File

@@ -0,0 +1,26 @@
@startdot spring-security-webflux-flow
digraph webfluxFlow {
rankdir=TB
edge [color="#A60738"]
node [color="#A60738"]
client [shape=box, label="客户端"]
endpoint [shape=box, label="处理端点"]
' tokenStorage [shape=box, label="令牌缓存"]
client -> SecurityFilterChain [label="HTTP请求"]
SecurityFilterChain -> AnonymousAuthenticationWebFilter [label="ServerWebExchange"]
AnonymousAuthenticationWebFilter -> SecurityContext [label="匿名Authentication"]
SecurityContext -> endpoint
SecurityFilterChain -> AuthenticationWebFilter [label="ServerWebExchange"]
AuthenticationWebFilter -> ReactivePreAuthenticatedAuthenticationManager [label="认证前的Authentication"]
ReactivePreAuthenticatedAuthenticationManager -> ReactiveUserDetailsService [label="用户认证信息"]
ReactiveUserDetailsService -> ReactivePreAuthenticatedAuthenticationManager [label="PreAuthenticatedAuthenticationToken"]
ReactivePreAuthenticatedAuthenticationManager -> AuthenticationWebFilter [label="PreAuthenticatedAuthenticationToken"]
AuthenticationWebFilter -> SecurityContext [label="认证后的Authentication"]
AuthenticationWebFilter -> JwtReactiveAuthenticationManager [label="认证前的Authentication"]
JwtReactiveAuthenticationManager -> AuthenticationWebFilter [label="BearerTokenAuthenticationToken"]
JwtReactiveAuthenticationManager -> JwtAuthenticationConverter [label="Jwt"]
JwtAuthenticationConverter -> JwtReactiveAuthenticationManager [label="JwtAuthenticationToken"]
}
@enddot