“鑷�"楂樼骇"宸ョ▼甯�(BUG宸ョ▼甯�)
涓�棰楁姌鑵剧殑蹇�馃挆
鍘熷垱涓嶆槗锛岀偣涓禐馃挆锛屾敮鎸佹敮鎸�
1.spring security 璁よ瘉鍜屾巿鏉冩祦绋�
甯歌璁よ瘉鍜屾巿鏉冩祦绋嬪彲浠ュ垎鎴愶細
-
A user is prompted to log in with a username and password 锛堢敤鎴风敤璐﹀瘑鐮佺櫥褰曪級
-
The system (successfully) verifies that the password is correct for the username锛堟牎楠屽瘑鐮佹纭�э級
-
The context information for that user is obtained (their list of roles and so on).锛堣幏鍙栫敤鎴蜂俊鎭痗ontext锛屽鏉冮檺锛�
-
A security context is established for the user锛堜负鐢ㄦ埛鍒涘缓security context锛�
-
The user proceeds, potentially to perform some operation which is potentially protected by an access control mechanism which checks the required permissions for the operation against the current security context information.锛堣闂潈闄愭帶鍒讹紝鏄惁鍏锋湁璁块棶鏉冮檺锛�
1.1 spring security 璁よ瘉
涓婅堪鍓嶄笁鐐逛负spring security璁よ瘉楠岃瘉鐜妭锛�
-
閫氬父閫氳繃AbstractAuthenticationProcessingFilter杩囨护鍣ㄥ皢璐﹀彿瀵嗙爜缁勮鎴怉uthentication瀹炵幇绫籙sernamePasswordAuthenticationToken锛�
-
灏唗oken浼犻�掔粰AuthenticationManager楠岃瘉鏄惁鏈夋晥锛岃�孉uthenticationManager閫氬父浣跨敤ProviderManager瀹炵幇绫绘潵妫�楠岋紱
-
AuthenticationManager璁よ瘉鎴愬姛鍚庡皢杩斿洖涓�涓嫢鏈夎缁嗕俊鎭殑Authentication object锛堝寘鎷潈闄愪俊鎭紝韬唤淇℃伅锛岀粏鑺備俊鎭紝浣嗗瘑鐮侀�氬父浼氳绉婚櫎锛夛紱
-
閫氳繃SecurityContextHolder.getContext().getAuthentication().getPrincipal()灏咥uthentication璁剧疆鍒皊ecurity context涓��
1.2 spring security璁块棶鎺堟潈
-
閫氳繃FilterSecurityInterceptor杩囨护鍣ㄥ叆鍙h繘鍏ワ紱
-
FilterSecurityInterceptor閫氳繃鍏剁户鎵跨殑鎶借薄绫荤殑AbstractSecurityInterceptor.beforeInvocation(Object object)鏂规硶杩涜璁块棶鎺堟潈锛屽叾涓秹鍙婁簡绫籄uthenticationManager銆丄ccessDecisionManager銆丼ecurityMetadataSource绛夈��
鏍规嵁涓婅堪鎻忚堪鐨勮繃绋嬶紝鎴戜滑鎺ヤ笅鏉ヤ富瑕佸幓鍒嗘瀽鍏朵腑娑夊強鐨勪竴涓婥omponent銆丼ervice銆丗ilter銆�
2.鏍稿績缁勪欢锛圕ore Component 锛�
2.1 SecurityContextHolder
SecurityContextHolder鎻愪緵瀵筍ecurityContext鐨勮闂紝瀛樺偍security context锛堢敤鎴蜂俊鎭�佽鑹叉潈闄愮瓑锛夛紝鑰屼笖鍏跺叿鏈変笅鍒楀偍瀛樼瓥鐣ュ嵆宸ヤ綔妯″紡锛�
-
SecurityContextHolder.MODE_THREADLOCAL锛堥粯璁わ級锛氫娇鐢═hreadLocal锛屼俊鎭彲渚涙绾跨▼涓嬬殑鎵�鏈夌殑鏂规硶浣跨敤锛屼竴绉嶄笌绾跨▼缁戝畾鐨勭瓥鐣ワ紝姝ゅぉ鐒跺緢閫傚悎Servlet Web搴旂敤銆�
-
SecurityContextHolder.MODE_GLOBAL锛氫娇鐢ㄤ簬鐙珛搴旂敤
-
SecurityContextHolder.MODE_INHERITABLETHREADLOCAL锛氬叿鏈夌浉鍚屽畨鍏ㄦ爣绀虹殑绾跨▼
淇敼SecurityContextHolder鐨勫伐浣滄ā寮忔湁涓ょ鏂规硶 :
-
璁剧疆涓�涓郴缁熷睘鎬�(system.properties) : spring.security.strategy;
-
璋冪敤SecurityContextHolder闈欐�佹柟娉晄etStrategyName()
鍦ㄩ粯璁hreadLocal绛栫暐涓紝SecurityContextHolder涓洪潤鎬佹柟娉曡幏鍙栫敤鎴蜂俊鎭负:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { String username = ((UserDetails)principal).getUsername(); } else { String username = principal.toString(); }
浣嗘槸涓�鑸笉闇�瑕佽嚜韬幓鑾峰彇銆� 鍏朵腑getAuthentication()杩斿洖涓�涓狝uthentication璁よ瘉涓讳綋锛屾帴涓嬫潵鍒嗘瀽Authentication銆乁serDetails缁嗚妭銆�
2.2 Authentication
public interface Authentication extends Principal, Serializable { //鏉冮檺淇℃伅鍒楄〃,榛樿GrantedAuthority鎺ュ彛鐨勪竴浜涘疄鐜扮被 Collection extends GrantedAuthority> getAuthorities(); //瀵嗙爜淇℃伅 Object getCredentials(); //缁嗚妭淇℃伅锛寃eb搴旂敤涓殑瀹炵幇鎺ュ彛閫氬父涓� WebAuthenticationDetails锛屽畠璁板綍浜嗚闂�呯殑ip鍦板潃鍜宻essionId鐨勫�� Object getDetails(); //閫氬父杩斿洖鍊间负UserDetails瀹炵幇绫� Object getPrincipal(); boolean isAuthenticated(); void setAuthenticated(boolean var1) throws IllegalArgumentException; }
鍓嶉潰涓や釜缁勪欢閮芥秹鍙婁簡UserDetails锛屼互鍙奊rantedAuthority鍏跺埌搴曟槸浠�涔堝憿锛�2.3灏忚妭鍒嗘瀽銆�
2.3 UserDetails&GrantedAuthority
UserDetails鎻愪緵浠庡簲鐢ㄧ▼搴忕殑DAO鎴栧叾浠栧畨鍏ㄦ暟鎹簮鏋勫缓Authentication瀵硅薄鎵�闇�鐨勪俊鎭紝鍖呭惈GrantedAuthority銆傚叾瀹樻柟瀹炵幇绫讳负User锛屽紑鍙戣�呭彲浠ュ疄鐜板叾鎺ュ彛鑷畾涔塙serDetails瀹炵幇绫汇�傚叾鎺ュ彛婧愮爜锛�
public interface UserDetails extends Serializable { 鈥� Collection extends GrantedAuthority> getAuthorities(); 鈥� String getPassword(); 鈥� String getUsername(); 鈥� boolean isAccountNonExpired(); 鈥� boolean isAccountNonLocked(); 鈥� boolean isCredentialsNonExpired(); 鈥� boolean isEnabled(); }
UserDetails涓嶢uthentication鎺ュ彛鍔熻兘绫讳技锛屽叾瀹炲惈涔夊嵆鏄疉uthentication涓虹敤鎴锋彁浜ょ殑璁よ瘉鍑瘉锛堣处鍙峰瘑鐮侊級锛孶serDetails涓虹郴缁熶腑鐢ㄦ埛姝g‘璁よ瘉鍑瘉锛屽湪UserDetailsService涓殑loadUserByUsername鏂规硶鑾峰彇姝g‘鐨勮璇佸嚟璇併�� 鍏朵腑鍦╣etAuthorities()鏂规硶涓幏鍙栧埌GrantedAuthority鍒楄〃鏄唬琛ㄧ敤鎴疯闂簲鐢ㄧ▼搴忔潈闄愯寖鍥达紝姝ょ被鏉冮檺閫氬父鏄�“role(瑙掕壊锛�”锛屼緥濡俁OLE_ADMINISTRATOR鎴朢OLE_HR_SUPERVISOR銆侴rantedAuthority鎺ュ彛甯歌鐨勫疄鐜扮被SimpleGrantedAuthority銆�
3. 鏍稿績鏈嶅姟绫伙紙Core Services锛�
3.1 AuthenticationManager銆丳roviderManager浠ュ強AuthenticationProvider
AuthenticationManager鏄璇佺浉鍏崇殑鏍稿績鎺ュ彛锛屾槸璁よ瘉涓�鍒囩殑璧风偣銆備絾甯歌鐨勮璇佹祦绋嬮兘鏄疉uthenticationManager瀹炵幇绫籔roviderManager澶勭悊锛岃�屼笖ProviderManager瀹炵幇绫诲熀浜庡鎵樿�呮ā寮忕淮鎶uthenticationProvider 鍒楄〃鐢ㄤ簬涓嶅悓鐨勮璇佹柟寮忋�備緥濡傦細
-
浣跨敤璐﹀彿瀵嗙爜璁よ瘉鏂瑰紡DaoAuthenticationProvider瀹炵幇绫伙紙缁ф壙浜咥bstractUserDetailsAuthenticationProvide鎶借薄绫伙級锛屽叾涓洪粯璁よ璇佹柟寮忥紝杩涜鏁版嵁搴撳簱鑾峰彇璁よ瘉鏁版嵁淇℃伅銆�
-
娓稿韬唤鐧诲綍璁よ瘉鏂瑰紡AnonymousAuthenticationProvider瀹炵幇绫�
-
浠巆ookies鑾峰彇璁よ瘉鏂瑰紡RememberMeAuthenticationProvider瀹炵幇绫�
AuthenticationProvider涓�
ProviderManager婧愮爜鍒嗘瀽锛�
public Authentication authenticate(Authentication authentication) throws AuthenticationException { Class extends Authentication> toTest = authentication.getClass(); AuthenticationException lastException = null; Authentication result = null; //AuthenticationProvider鍒楄〃渚濇璁よ瘉 for (AuthenticationProvider provider : getProviders()) { if (!provider.supports(toTest)) { continue; } try { //姣忎釜AuthenticationProvider杩涜璁よ瘉 result = provider.authenticate(authentication) if (result != null) { copyDetails(authentication, result); break; } } .... catch (AuthenticationException e) { lastException = e; } } //杩涜鐖剁被AuthenticationProvider杩涜璁よ瘉 if (result == null && parent != null) { // Allow the parent to try. try { result = parent.authenticate(authentication); } catch (AuthenticationException e) { lastException = e; } } // 濡傛灉鏈堿uthentication淇℃伅锛屽垯鐩存帴杩斿洖 if (result != null) { if (eraseCredentialsAfterAuthentication && (result instanceof CredentialsContainer)) { //娓呴櫎瀵嗙爜 ((CredentialsContainer) result).eraseCredentials(); } //鍙戝竷鐧诲綍鎴愬姛浜嬩欢 eventPublisher.publishAuthenticationSuccess(result); return result; } //濡傛灉閮芥病璁よ瘉鎴愬姛锛屾姏鍑哄紓甯� if (lastException == null) { lastException = new ProviderNotFoundException(messages.getMessage( "ProviderManager.providerNotFound", new Object[] { toTest.getName() }, "No AuthenticationProvider found for {0}")); } prepareException(lastException, authentication); throw lastException; }
ProviderManager 涓殑AuthenticationProvider鍒楄〃锛屼細渚濈収娆″簭鍘昏璇侊紝榛樿绛栫暐涓嬶紝鍙渶瑕侀�氳繃涓�涓狝uthenticationProvider鐨勮璇侊紝鍗冲彲琚涓烘槸鐧诲綍鎴愬姛锛岃�屼笖AuthenticationProvider璁よ瘉鎴愬姛鍚庤繑鍥炰竴涓狝uthentication瀹炰綋锛屽苟涓轰簡瀹夊叏浼氳繘琛屾竻闄ゅ瘑鐮併�傚鏋滄墍鏈夎璇佸櫒閮芥棤娉曡璇佹垚鍔燂紝鍒橮roviderManager 浼氭姏鍑轰竴涓狿roviderNotFoundException寮傚父銆�
3.2 UserDetailsService
UserDetailsService鎺ュ彛浣滅敤鏄粠鐗瑰畾鐨勫湴鏂硅幏鍙栬璇佺殑鏁版嵁婧愶紙璐﹀彿銆佸瘑鐮侊級銆傚浣曡幏鍙栧埌绯荤粺涓纭殑璁よ瘉鍑瘉锛岄�氳繃loadUserByUsername(String username)鑾峰彇璁よ瘉淇℃伅锛岃�屼笖鍏跺彧鏈変竴涓柟娉曪細
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
鍏跺父瑙佺殑瀹炵幇绫讳粠鏁版嵁鑾峰彇鐨凧dbcDaoImpl瀹炵幇绫伙紝浠庡唴瀛樹腑鑾峰彇鐨処nMemoryUserDetailsManager瀹炵幇绫伙紝涓嶈繃鎴戜滑鍙互瀹炵幇鍏舵帴鍙h嚜瀹氫箟UserDetailsService瀹炵幇绫伙紝濡備笅锛�
public class CustomUserService implements UserDetailsService { @Autowired //鐢ㄦ埛mapper private UserInfoMapper userInfoMapper; @Autowired //鐢ㄦ埛鏉冮檺mapper private PermissionInfoMapper permissionInfoMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfoDTO userInfo = userInfoMapper.getUserInfoByUserName(username); if (userInfo != null) { ListpermissionInfoDTOS = permissionInfoMapper.findByAdminUserId(userInfo.getId()); List grantedAuthorityList = new ArrayList<>(); //缁勮鏉冮檺GrantedAuthority object for (PermissionInfoDTO permissionInfoDTO : permissionInfoDTOS) { if (permissionInfoDTO != null && permissionInfoDTO.getPermissionName() != null) { GrantedAuthority grantedAuthority = new SimpleGrantedAuthority( permissionInfoDTO.getPermissionName()); grantedAuthorityList.add(grantedAuthority); } } //杩斿洖鐢ㄦ埛淇℃伅 return new User(userInfo.getUserName(), userInfo.getPasswaord(), grantedAuthorityList); }else { //鎶涘嚭鐢ㄦ埛涓嶅瓨鍦ㄥ紓甯� throw new UsernameNotFoundException("admin" + username + "do not exist"); } } }
3.3 AccessDecisionManager&SecurityMetadataSource
AccessDecisionManager鏄敱AbstractSecurityInterceptor璋冪敤锛岃礋璐e仛鍑烘渶缁堢殑璁块棶鎺у埗鍐崇瓥銆�
AccessDecisionManager鎺ュ彛婧愮爜锛�
//璁块棶鎺у埗鍐崇瓥 void decide(Authentication authentication, Object secureObject,Collectionattrs) throws AccessDeniedException; //鏄惁鏀寔澶勭悊浼犻�掔殑ConfigAttribute boolean supports(ConfigAttribute attribute); //纭class鏄惁涓篈ccessDecisionManager boolean supports(Class clazz);
SecurityMetadataSource鍖呭惈鐫�AbstractSecurityInterceptor璁块棶鎺堟潈鎵�闇�鐨勫厓鏁版嵁锛堝姩鎬乽rl銆佸姩鎬佹巿鏉冩墍闇�鐨勬暟鎹級锛屽湪AbstractSecurityInterceptor鎺堟潈妯″潡涓粨鍚圓ccessDecisionManager杩涜璁块棶鎺堟潈銆傚叾娑夊強浜咰onfigAttribute銆� SecurityMetadataSource鎺ュ彛锛�
CollectiongetAttributes(Object object) throws IllegalArgumentException; 鈥� Collection getAllConfigAttributes(); 鈥� boolean supports(Class> clazz);
鎴戜滑杩樺彲浠ヨ嚜瀹氫箟SecurityMetadataSource鏁版嵁婧愶紝瀹炵幇鎺ュ彛FilterInvocationSecurityMetadataSource銆備緥锛�
public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { public ListgetAttributes(Object object) { FilterInvocation fi = (FilterInvocation) object; String url = fi.getRequestUrl(); String httpMethod = fi.getRequest().getMethod(); List attributes = new ArrayList (); 鈥� // Lookup your database (or other source) using this information and populate the // list of attributes 鈥� return attributes; } 鈥� public Collection getAllConfigAttributes() { return null; } 鈥� public boolean supports(Class> clazz) { return FilterInvocation.class.isAssignableFrom(clazz); } }
3.4 PasswordEncoder
涓轰簡瀛樺偍瀹夊叏锛屼竴鑸瀵瑰瘑鐮佽繘琛岀畻娉曞姞瀵嗭紝鑰宻pring security鎻愪緵浜嗗姞瀵哖asswordEncoder鎺ュ彛銆傚叾瀹炵幇绫绘湁浣跨敤BCrypt hash绠楁硶瀹炵幇鐨凚CryptPasswordEncoder锛孲Crypt hashing 绠楁硶瀹炵幇鐨凷CryptPasswordEncoder瀹炵幇绫伙紝瀹炵幇绫诲唴閮ㄥ疄鐜板彲鐪嬫簮鐮佸垎鏋愩�傝�孭asswordEncoder鎺ュ彛鍙湁涓や釜鏂规硶锛�
public interface PasswordEncoder { //瀵嗙爜鍔犲瘑 String encode(CharSequence rawPassword); //瀵嗙爜閰嶅 boolean matches(CharSequence rawPassword, String encodedPassword); }
4 鏍稿績 Security 杩囨护鍣紙Core Security Filters锛�
4.1 FilterSecurityInterceptor
FilterSecurityInterceptor鏄疭pring security鎺堟潈妯″潡鍏ュ彛锛岃绫绘牴鎹闂殑鐢ㄦ埛鐨勮鑹诧紝鏉冮檺鎺堟潈璁块棶閭d簺璧勬簮锛堣闂壒瀹氳矾寰勫簲璇ュ叿澶囩殑鏉冮檺锛夈�� FilterSecurityInterceptor灏佽FilterInvocation瀵硅薄杩涜鎿嶄綔锛屾墍鏈夌殑璇锋眰鍒颁簡杩欎竴涓猣ilter锛屽鏋滆繖涓猣ilter涔嬪墠娌℃湁鎵ц杩囩殑璇濓紝閭d箞棣栧厛鎵ц鍏剁埗绫籄bstractSecurityInterceptor鎻愪緵鐨処nterceptorStatusToken token = super.beforeInvocation(fi)锛屽湪姝ゆ柟娉曚腑浣跨敤AuthenticationManager鑾峰彇Authentication涓敤鎴疯鎯咃紝浣跨敤ConfigAttribute灏佽宸插畾涔夊ソ璁块棶鏉冮檺璇︽儏锛屽苟浣跨敤AccessDecisionManager.decide()鏂规硶杩涜璁块棶鏉冮檺鎺у埗銆� FilterSecurityInterceptor婧愮爜鍒嗘瀽锛�
public void invoke(FilterInvocation fi) throws IOException, ServletException { if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null) && observeOncePerRequest) { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } else { // first time this request being called, so perform security checking if (fi.getRequest() != null && observeOncePerRequest) { fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE); } //鍥炶皟鍏剁户鎵跨殑鎶借薄绫籄bstractSecurityInterceptor鐨勬柟娉� InterceptorStatusToken token = super.beforeInvocation(fi); 鈥� try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.finallyInvocation(token); } 鈥� super.afterInvocation(token, null); } }
AbstractSecurityInterceptor婧愮爜鍒嗘瀽锛�
protected InterceptorStatusToken beforeInvocation(Object object) { .... //鑾峰彇鎵�鏈夎闂潈闄愶紙url-role锛夊睘鎬у垪琛紙宸插畾涔夊湪鏁版嵁搴撴垨鑰呭叾浠栧湴鏂癸級 Collectionattributes = this.obtainSecurityMetadataSource() .getAttributes(object); .... //鑾峰彇璇ョ敤鎴疯闂俊鎭紙鍖呮嫭url锛岃闂潈闄愶級 Authentication authenticated = authenticateIfRequired(); 鈥� // Attempt authorization try { //杩涜鎺堟潈璁块棶 this.accessDecisionManager.decide(authenticated, object, attributes); }catch .... }
4.2 UsernamePasswordAuthenticationFilter
UsernamePasswordAuthenticationFilter浣跨敤username鍜宲assword琛ㄥ崟鐧诲綍浣跨敤鐨勮繃婊ゅ櫒锛屼篃鏄渶涓哄父鐢ㄧ殑杩囨护鍣ㄣ�傚叾婧愮爜锛�
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { //鑾峰彇琛ㄥ崟涓殑鐢ㄦ埛鍚嶅拰瀵嗙爜 String username = obtainUsername(request); String password = obtainPassword(request); ... username = username.trim(); //缁勮鎴恥sername+password褰㈠紡鐨則oken UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); //浜ょ粰鍐呴儴鐨凙uthenticationManager鍘昏璇侊紝骞惰繑鍥炶璇佷俊鎭� return this.getAuthenticationManager().authenticate(authRequest); }
鍏朵富瑕佷唬鐮佷负鍒涘缓UsernamePasswordAuthenticationToken鐨凙uthentication瀹炰綋浠ュ強璋冪敤AuthenticationManager杩涜authenticate璁よ瘉锛屾牴鎹璇佺粨鏋滄墽琛宻uccessfulAuthentication鎴栬�卽nsuccessfulAuthentication锛屾棤璁烘垚鍔熷け璐ワ紝涓�鑸殑瀹炵幇閮芥槸杞彂鎴栬�呴噸瀹氬悜绛夊鐞嗭紝涓嶅啀缁嗙┒AuthenticationSuccessHandler鍜孉uthenticationFailureHandle銆傚叴瓒g殑鍙互鐮旂┒涓�涓嬪叾鐖剁被AbstractAuthenticationProcessingFilter杩囨护鍣ㄣ��
4.3 AnonymousAuthenticationFilter
AnonymousAuthenticationFilter鏄尶鍚嶇櫥褰曡繃婊ゅ櫒锛屽畠浣嶄簬甯哥敤鐨勮韩浠借璇佽繃婊ゅ櫒锛堝UsernamePasswordAuthenticationFilter銆丅asicAuthenticationFilter銆丷ememberMeAuthenticationFilter锛変箣鍚庯紝鎰忓懗鐫�鍙湁鍦ㄤ笂杩拌韩浠借繃婊ゅ櫒鎵ц瀹屾瘯鍚庯紝SecurityContext渚濇棫娌℃湁鐢ㄦ埛淇℃伅锛孉nonymousAuthenticationFilter璇ヨ繃婊ゅ櫒鎵嶄細鏈夋剰涔�——鍩轰簬鐢ㄦ埛涓�涓尶鍚嶈韩浠姐�� AnonymousAuthenticationFilter婧愮爜鍒嗘瀽锛�
public class AnonymousAuthenticationFilter extends GenericFilterBean implements InitializingBean { ... public AnonymousAuthenticationFilter(String key) { this(key, "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")); } ... public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 鈥� if (SecurityContextHolder.getContext().getAuthentication() == null) { //鍒涘缓鍖垮悕鐧诲綍Authentication鐨勪俊鎭� SecurityContextHolder.getContext().setAuthentication( createAuthentication((HttpServletRequest) req)); ... } 鈥� chain.doFilter(req, res); } //鍒涘缓鍖垮悕鐧诲綍Authentication鐨勪俊鎭柟娉� protected Authentication createAuthentication(HttpServletRequest request) { AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key, principal, authorities); auth.setDetails(authenticationDetailsSource.buildDetails(request)); return auth; } }
4.4 SecurityContextPersistenceFilter
SecurityContextPersistenceFilter鐨勪袱涓富瑕佷綔鐢ㄤ究鏄痳equest鏉ヤ复鏃讹紝鍒涘缓SecurityContext瀹夊叏涓婁笅鏂囦俊鎭拰request缁撴潫鏃舵竻绌篠ecurityContextHolder銆傛簮鐮佸悗缁垎鏋愩��
灏忚妭鎬荤粨锛�
. AbstractAuthenticationProcessingFilter:涓昏澶勭悊鐧诲綍 . FilterSecurityInterceptor:涓昏澶勭悊閴存潈
鎬荤粨
缁忚繃涓婇潰瀵规牳蹇冪殑Component銆丼ervice銆丗ilter鍒嗘瀽锛屽垵姝ヤ簡瑙d簡Spring Security宸ヤ綔鍘熺悊浠ュ強璁よ瘉鍜屾巿鏉冨伐浣滄祦绋嬨�係pring Security璁よ瘉鍜屾巿鏉冭繕鏈夊緢澶氳礋璐g殑杩囩▼闇�瑕佹繁鍏ヤ簡瑙o紝鎵�浠ヤ笅娆′細瀵硅璇佹ā鍧楀拰鎺堟潈妯″潡杩涜鏇村叿浣撳伐浣滄祦绋嬪垎鏋愪互鍙婃渚嬪憟鐜般��
鍚勪綅鐪嬪畼杩樺彲浠ュ悧锛熷枩娆㈢殑璇濓紝鍔ㄥ姩鎵嬫寚鐐逛釜璧烉煉楋紝鐐逛釜鍏虫敞鍛楋紒锛佽阿璋㈡敮鎸侊紒