亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Spring Security的Web應(yīng)用和指紋登錄實(shí)踐

 更新時(shí)間:2019年03月04日 14:22:36   作者:劉少飛  
這篇文章主要介紹了詳解Spring Security的Web應(yīng)用和指紋登錄實(shí)踐,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

前言

Java 開發(fā)人員在解決 Web 應(yīng)用安全相關(guān)的問題時(shí),通常會(huì)采用兩個(gè)非常流行的安全框架,Shiro 和 Spring Security。Shiro 配置簡單,上手快,滿足一般應(yīng)用的安全需求,但是功能相對(duì)單一。Spring Security 安全粒度細(xì),與 Spring Framework 無縫集成,滿足絕大多數(shù)企業(yè)級(jí)應(yīng)用的安全需求,但是配置復(fù)雜,學(xué)習(xí)曲線陡峭。

Spring Security 相對(duì) Shiro 功能強(qiáng)大,并且 Spring Framework,Spring Boot,Spring Cloud 對(duì) Spring Security 的支持更加友好 (畢竟是 "親兒子")。本文將介紹 Spring Security 的架構(gòu)設(shè)計(jì)、核心組件,在 Web 應(yīng)用中的開發(fā)方式,最后以一個(gè)指紋登錄的實(shí)例收尾。

Spring Security 核心設(shè)計(jì)

Spring Security 有五個(gè)核心組件:SecurityContext、SecurityContextHolder、Authentication、Userdetails 和 AuthenticationManager。下面分別介紹一下各個(gè)組件。

SecurityContext

SecurityContext 即安全上下文,關(guān)聯(lián)當(dāng)前用戶的安全信息。用戶通過 Spring Security 的校驗(yàn)之后,SecurityContext 會(huì)存儲(chǔ)驗(yàn)證信息,下文提到的 Authentication 對(duì)象包含當(dāng)前用戶的身份信息。SecurityContext 的接口簽名如清單 1 所示:

清單 1. SecurityContext 的接口簽名

public interface SecurityContext extends Serializable {
    Authentication getAuthentication();
    void setAuthentication(Authentication authentication);
}

SecurityContext 存儲(chǔ)在 SecurityContextHolder 中。

SecurityContextHolder
SecurityContextHolder 存儲(chǔ) SecurityContext 對(duì)象。SecurityContextHolder 是一個(gè)存儲(chǔ)代理,有三種存儲(chǔ)模式分別是:

  • MODE_THREADLOCAL:SecurityContext 存儲(chǔ)在線程中。
  • MODE_INHERITABLETHREADLOCAL:SecurityContext 存儲(chǔ)在線程中,但子線程可以獲取到父線程中的 SecurityContext。
  • MODE_GLOBAL:SecurityContext 在所有線程中都相同。

SecurityContextHolder 默認(rèn)使用 MODE_THREADLOCAL 模式,SecurityContext 存儲(chǔ)在當(dāng)前線程中。調(diào)用 SecurityContextHolder 時(shí)不需要顯示的參數(shù)傳遞,在當(dāng)前線程中可以直接獲取到 SecurityContextHolder 對(duì)象。但是對(duì)于很多 C 端的應(yīng)用(音樂播放器,游戲等等),用戶登錄完畢,在軟件的整個(gè)生命周期中只有當(dāng)前登錄用戶,面對(duì)這種情況 SecurityContextHolder 更適合采用 MODE_GLOBAL 模式,SecurityContext 相當(dāng)于存儲(chǔ)在應(yīng)用的進(jìn)程中,SecurityContext 在所有線程中都相同。

Authentication

Authentication 即驗(yàn)證,表明當(dāng)前用戶是誰。什么是驗(yàn)證,比如一組用戶名和密碼就是驗(yàn)證,當(dāng)然錯(cuò)誤的用戶名和密碼也是驗(yàn)證,只不過 Spring Security 會(huì)校驗(yàn)失敗。Authentication 接口簽名如清單 2 所示:

清單 2. Authentication 的接口簽名

public interface Authentication extends Principal, Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    Object getCredentials();
    Object getDetails();
    Object getPrincipal();
    boolean isAuthenticated();
    void setAuthenticated(boolean isAuthenticated);
}

Authentication 是一個(gè)接口,實(shí)現(xiàn)類都會(huì)定義 authorities,credentials,details,principal,authenticated 等字段,具體含義如下:

  • getAuthorities: 獲取用戶權(quán)限,一般情況下獲取到的是用戶的角色信息。
  • getCredentials: 獲取證明用戶認(rèn)證的信息,通常情況下獲取到的是密碼等信息。
  • getDetails: 獲取用戶的額外信息,比如 IP 地址、經(jīng)緯度等。
  • getPrincipal: 獲取用戶身份信息,在未認(rèn)證的情況下獲取到的是用戶名,在已認(rèn)證的情況下獲取到的是 UserDetails (暫時(shí)理解為,當(dāng)前應(yīng)用用戶對(duì)象的擴(kuò)展)。
  • isAuthenticated: 獲取當(dāng)前 Authentication 是否已認(rèn)證。
  • setAuthenticated: 設(shè)置當(dāng)前 Authentication 是否已認(rèn)證。

在驗(yàn)證前,principal 填充的是用戶名,credentials 填充的是密碼,detail 填充的是用戶的 IP 或者經(jīng)緯度之類的信息。通過驗(yàn)證后,Spring Security 對(duì) Authentication 重新注入,principal 填充用戶信息(包含用戶名、年齡等), authorities 會(huì)填充用戶的角色信息,authenticated 會(huì)被設(shè)置為 true。重新注入的 Authentication 會(huì)被填充到 SecurityContext 中。

UserDetails

UserDetails 提供 Spring Security 需要的用戶核心信息。UserDetails 的接口簽名如清單 3 所示:

清單 3. UserDetails 的接口簽名

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    String getPassword();
    String getUsername();
    boolean isAccountNonExpired();
    boolean isAccountNonLocked();
    boolean isCredentialsNonExpired();
    boolean isEnabled();
}

UserDetails 用 isAccountNonExpired, isAccountNonLocked,isCredentialsNonExpired,isEnabled 表示用戶的狀態(tài)(與下文中提到的 DisabledException,LockedException,BadCredentialsException 相對(duì)應(yīng)),具體含義如下:

  • getAuthorites:獲取用戶權(quán)限,本質(zhì)上是用戶的角色信息。
  • getPassword: 獲取密碼。
  • getUserName: 獲取用戶名。
  • isAccountNonExpired: 賬戶是否過期。
  • isAccountNonLocked: 賬戶是否被鎖定。
  • isCredentialsNonExpired: 密碼是否過期。
  • isEnabled: 賬戶是否可用。

UserDetails 也是一個(gè)接口,實(shí)現(xiàn)類都會(huì)繼承當(dāng)前應(yīng)用的用戶信息類,并實(shí)現(xiàn) UserDetails 的接口。假設(shè)應(yīng)用的用戶信息類是 User,自定義的 CustomUserdetails 繼承 User 類并實(shí)現(xiàn) UserDetails 接口。

AuthenticationManager

AuthenticationManager 負(fù)責(zé)校驗(yàn) Authentication 對(duì)象。在 AuthenticationManager 的 authenticate 函數(shù)中,開發(fā)人員實(shí)現(xiàn)對(duì) Authentication 的校驗(yàn)邏輯。如果 authenticate 函數(shù)校驗(yàn)通過,正常返回一個(gè)重新注入的 Authentication 對(duì)象;校驗(yàn)失敗,則拋出 AuthenticationException 異常。authenticate 函數(shù)簽名如清單 4 所示:

清單 4. authenticate 函數(shù)簽名

Authentication authenticate(Authentication authentication)throws AuthenticationException;

AuthenticationManager 可以將異常拋出的更加明確:

  • 當(dāng)用戶不可用時(shí)拋出 DisabledException。
  • 當(dāng)用戶被鎖定時(shí)拋出 LockedException。
  • 當(dāng)用戶密碼錯(cuò)誤時(shí)拋出 BadCredentialsException。

重新注入的 Authentication 會(huì)包含當(dāng)前用戶的詳細(xì)信息,并且被填充到 SecurityContext 中,這樣 Spring Security 的驗(yàn)證流程就完成了,Spring Security 可以識(shí)別到 "你是誰"。

基本校驗(yàn)流程示例

下面采用 Spring Security 的核心組件寫一個(gè)最基本的用戶名密碼校驗(yàn)示例,如清單 5 所示:

清單 5. Spring Security 核心組件偽代碼

AuthenticationManager amanager = new CustomAuthenticationManager();
Authentication namePwd = new CustomAuthentication(“name”, “password”);
try {
    Authentication result = amanager.authenticate(namePwd);
    SecurityContextHolder.getContext.setAuthentication(result);
} catch(AuthenticationException e) {
    // TODO 驗(yàn)證失敗
}

Spring Security 的核心組件易于理解,其基本校驗(yàn)流程是: 驗(yàn)證信息傳遞過來,驗(yàn)證通過,將驗(yàn)證信息存儲(chǔ)到 SecurityContext 中;驗(yàn)證失敗,做出相應(yīng)的處理。

Spring Security 在 Web 中的設(shè)計(jì)

Spring Security 的一個(gè)常見應(yīng)用場景就是 Web。下面討論 Spring Security 在 Web 中的使用方式。

Spring Security 最簡登錄實(shí)例

Spring Security 在 Web 中的使用相對(duì)要復(fù)雜一點(diǎn),會(huì)涉及到很多組件。現(xiàn)在給出自定義登錄的偽代碼,如清單 6 所示。您可以點(diǎn)擊這里,查看完整的代碼。

清單 6. Web 登錄偽代碼

@Controller
public class UserController { 
 
    @PostMapping(“/login”)
    public void login(String name, String password){
       matchNameAndPassword(name, password);
       User user = getUser(name);
       Authentication auth = new CustomAuthentication(user, password);
       auth.setAuthenticated(true);
       SecurityContextHolder.getContext.setAuthentication(auth);
    }
}

觀察代碼會(huì)發(fā)現(xiàn),如果用 Spring Security 來集成已存在的登錄邏輯,真正和 Spring Security 關(guān)聯(lián)的代碼只有短短 3 行。驗(yàn)證邏輯可以不經(jīng)過 AuthenticationManager,真正需要做的就是把經(jīng)過驗(yàn)證的用戶信息注入到 Authentication 中,并將 Authentication 填充到 SecurityContext 中。在實(shí)際情況中,登錄邏輯的確可以這樣寫,尤其是已經(jīng)存在登錄邏輯的時(shí)候,通常會(huì)這樣寫。這樣寫雖然方便,但是不符合 Spring Security 在 Web 中的架構(gòu)設(shè)計(jì)。

下面視頻中會(huì)介紹已存在的項(xiàng)目如何與 Spring Security 進(jìn)行集成,要求對(duì)已存在的登錄驗(yàn)證邏輯不變,但可以使用 Spring Security 的優(yōu)秀特性和功能。

視頻地址:https://mediacenter.ibm.com/media/0_qvbohipj

項(xiàng)目地址:https://github.com/springAppl/yuchigong

Spring Security 在 Web 中的核心組件

下面介紹在 Web 環(huán)境中 Spring Security 的核心組件。

FilterChainProxy

FilterChaniProxy 是 FilterChain 代理。FilterChain 維護(hù)了一個(gè) Filter 隊(duì)列,這些 Filter 為 Spring Security 提供了強(qiáng)大的功能。一個(gè)很常見的問題是:Spring Security 在 Web 中的入口是哪里?答案是 Filter。Spring Security 在 Filter 中創(chuàng)建 Authentication 對(duì)象,并調(diào)用 AuthenticationManager 進(jìn)行校驗(yàn)。Spring Security 選擇 Filter,而沒有采用上文中 Controller 的方式有以下優(yōu)點(diǎn)。Spring Security 依賴 J2EE 標(biāo)準(zhǔn),無需依賴特定的 MVC 框架。另一方面 Spring MVC 通過 Servlet 做請(qǐng)求轉(zhuǎn)發(fā),如果 Spring Security 采用 Servlet,那么 Spring Security 和 Spring MVC 的集成會(huì)存在問題。FilterChain 維護(hù)了很多 Filter,每個(gè) Filter 都有自己的功能,因此在 Spring Security 中添加新功能時(shí),推薦通過 Filter 的方式來實(shí)現(xiàn)。

ProviderManager

ProviderManager 是 AuthenticationManager 的實(shí)現(xiàn)類。ProviderManager 并沒有實(shí)現(xiàn)對(duì) Authentication 的校驗(yàn)功能,而是采用代理模式將校驗(yàn)功能交給 AuthenticationProvider 去實(shí)現(xiàn)。這樣設(shè)計(jì)是因?yàn)樵?Web 環(huán)境中可能會(huì)支持多種不同的驗(yàn)證方式,比如用戶名密碼登錄、短信登錄、指紋登錄等等,如果每種驗(yàn)證方式的代碼都寫在 ProviderManager 中,想想都是災(zāi)難。因此為每種驗(yàn)證方式提供對(duì)應(yīng)的 AuthenticationProvider,ProviderManager 將驗(yàn)證任務(wù)代理給對(duì)應(yīng)的 AuthenticationProvider,這是一種不錯(cuò)的解決方案。在 ProviderManager 中可以找到以下代碼,如清單 7 所示:

清單 7. ProviderManager 代碼片段

private List<AuthenticationProvider> providers;
public Authentication authenticate(Authentication authentication)
           throws AuthenticationException {
    ......
    for (AuthenticationProvider provider : getProviders()) {
       if (!provider.supports(toTest)) {
           continue;
       }
       try {
           result = provider.authenticate(authentication);
           if (result != null) {
               copyDetails(authentication, result);
               break;
           }
       }
    }
}

ProviderManager 維護(hù)了一個(gè) AuthenticationProvider 隊(duì)列。當(dāng) Authentication 傳遞進(jìn)來時(shí),ProviderManager 通過 supports 函數(shù)查找支持校驗(yàn)的 AuthenticationProvider。如果沒有找到支持的 AuthenticationProvider 將拋出 ProviderNotFoundException 異常。

AuthenticationProvider

AuthenticationProvider 是在 Web 環(huán)境中真正對(duì) Authentication 進(jìn)行校驗(yàn)的組件。其接口簽名如清單 8 所示:

清單 8. AuthenticationProvider 的接口簽名

public interface AuthenticationProvider {
    Authentication authenticate(Authentication authentication)
           throws AuthenticationException;
    boolean supports(Class<?> authentication);
}

其中,authenticate 函數(shù)用于校驗(yàn) Authentication 對(duì)象;supports 函數(shù)用于判斷 provider 是否支持校驗(yàn) Authentication 對(duì)象。

當(dāng)應(yīng)用添加新的驗(yàn)證方式時(shí),驗(yàn)證邏輯需要寫在對(duì)應(yīng) AuthenticationProvider 中的 authenticate 函數(shù)中。驗(yàn)證通過返回一個(gè)重新注入的 Authentication,驗(yàn)證失敗拋出 AuthenticationException 異常。

Spring Security 在 Web 中的認(rèn)證示例

下面的視頻中會(huì)介紹采用 Spring Security 提供的 UsernamePasswordAuthenticationFilter 實(shí)現(xiàn)登錄驗(yàn)證。

視頻地址:https://mediacenter.ibm.com/media/0_7vq75cue

項(xiàng)目地址:https://github.com/springAppl/rachel

下面以用戶名密碼登錄為例來梳理 Spring Security 在 Web 中的認(rèn)證流程。上文提到 Spring Security 是以 Filter 來作為校驗(yàn)的入口點(diǎn)。在用戶名密碼登錄中對(duì)應(yīng)的 Filter 是 UsernamePasswordAuthenticationFilter。attemptAuthentication 函數(shù)會(huì)執(zhí)行調(diào)用校驗(yàn)的邏輯。在 attemptAuthentication 函數(shù)中,可以找到以下代碼,如清單 9 所示:

清單 9. attemptAuthentication 函數(shù)代碼片段

public Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse 
response) throws AuthenticationException {
    ......
    UsernamePasswordAuthenticationToken authRequest = new 
UsernamePasswordAuthenticationToken(username, password);
    setDetails(request, authRequest);
    return this.getAuthenticationManager().authenticate(authRequest);
}

attemptAuthentication 函數(shù)會(huì)調(diào)用 AuthenticationManager 執(zhí)行校驗(yàn)邏輯,并獲取到重新注入后的 Authentication。在 UsernamePasswordAuthenticationFilter 父類 AbstractAuthenticationProcessingFilter 的 successfulAuthentication 函數(shù)中發(fā)現(xiàn)以下代碼,如清單 10 所示:

清單 10. successAuthentication 函數(shù)

protected void successfulAuthentication(HttpServletRequest request,
           HttpServletResponse response, FilterChain chain, Authentication 
authResult)throws IOException, ServletException {
    ......     SecurityContextHolder.getContext().setAuthentication(authResult);
    ......
}

successfulAuthentication 函數(shù)會(huì)把重新注入的 Authentication 填充到 SecurityContext 中,完成驗(yàn)證。

在 Web 中,AuthenticationManager 的實(shí)現(xiàn)類 ProviderManager 并沒有實(shí)現(xiàn)校驗(yàn)邏輯,而是代理給 AuthenticationProvider, 在用戶名密碼登錄中就是 DaoAuthenticationProvider。DaoAuthenticationProvider 主要完成 3 個(gè)功能:獲取 UserDetails、校驗(yàn)密碼、重新注入 Authentication。在 authenticate 函數(shù)中發(fā)現(xiàn)以下代碼,如清單 11 所示:

清單 11. DaoAuthenticationProvider.authenticate 函數(shù)簽名

public Authentication authenticate(Authentication authentication)
           throws AuthenticationException {
    ......
    // 獲取 UserDetails
    UserDetails user = this.userCache.getUserFromCache(username);
    if (user == null) {
       cacheWasUsed = false;
       try {
           user = retrieveUser(username,         
    (UsernamePasswordAuthenticationToken) authentication);
       }
       ......
    }
    ......
    try {
       ......
       //校驗(yàn)密碼
       additionalAuthenticationChecks(
           user,
       (UsernamePasswordAuthenticationToken) authentication
       );
    }
    ......
    // 從新注入 Authentication
    return createSuccessAuthentication(
           principalToReturn, 
           authentication, 
           user
        );
}

首先從 userCache 緩存中查找 UserDetails, 如果緩存中沒有獲取到,調(diào)用 retrieveUser 函數(shù)獲取 UserDetails。retrieveUser 函數(shù)簽名如清單 12 所示:

清單 12. retrieveUser 函數(shù)簽名

protected final UserDetails retrieveUser(String username,
    UsernamePasswordAuthenticationToken authentication)
           throws AuthenticationException {
    UserDetails loadedUser;
    try {
        loadedUser = this.getUserDetailsService().loadUserByUsername(username);
    }
    ......
    return loadedUser;
}

retrieveUser 函數(shù)調(diào)用 UserDetailsService 獲取 UserDetails 對(duì)象。UserDetailsService 接口簽名如清單 13 所示:

清單 13. UserDetailsService 接口簽名

public interface UserDetailsService {
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

UserDetailsService 非常簡單,只有一個(gè) loadUserByUserName 函數(shù),函數(shù)參數(shù)雖然名為 username,但只要是用戶的唯一標(biāo)識(shí)符即可。下面是基于數(shù)據(jù)庫存儲(chǔ)的簡單示例, 如清單 14 所示:

清單 14. CustomUserDetailsService 類簽名

public class CustomUserDetailsService implements UserDetailsService {
   
  @Autowired
  private UserDao userDao;
 
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
{
    User user = userDao.findByName(username);
    if(Objects.isNull(user)) {
      throw new UsernameNotFoundException();
    }
    UserDetails details = new CustomUserDetails(user);
    return details;
  }
}

調(diào)用 UserDao 獲取 User 對(duì)象,將 User 對(duì)象包裝成 UserDetails 對(duì)象。如果沒有找到 User 對(duì)象,需要拋出 UsernameNotFoundException 異常。

DaoAuthenticationProvider 密碼校驗(yàn)調(diào)用 additionalAuthenticationChecks 函數(shù),具體通過 PasswordEncoder 比對(duì)用戶輸入的密碼和存儲(chǔ)在應(yīng)用中的密碼是否相等,如果不相等,拋出 BadCredentialsException 異常。

DaoAuthenticationProvider 對(duì) Authentication 對(duì)象的重新注入通過調(diào)用 createSuccessAuthentication 函數(shù), 如清單 15 所示:

清單 15. createSuccessAuthentication 函數(shù)簽名

protected Authentication createSuccessAuthentication(Object principal,
           Authentication authentication, UserDetails user) {
    UsernamePasswordAuthenticationToken result = new    
    UsernamePasswordAuthenticationToken(
        principal, 
        authentication.getCredentials(),     
        authoritiesMapper.mapAuthorities(user.getAuthorities())
    );
    result.setDetails(authentication.getDetails());
    return result;
}

以上就是 Spring Security 在 Web 環(huán)境中對(duì)于用戶名密碼校驗(yàn)的整個(gè)流程,簡言之:

  1. UsernamePasswordAuthenticationFilter 接受用戶名密碼登錄請(qǐng)求,將 Authentication 傳遞給 ProviderManager 進(jìn)行校驗(yàn)。
  2. ProviderManager 將校驗(yàn)任務(wù)代理給 DaoAuthenticationProvider。
  3. DaoAuthenticationProvider 對(duì) Authentication 的用戶名和密碼進(jìn)行校驗(yàn),校驗(yàn)通過后返回重新注入的 Authentication 對(duì)象。
  4. UsernamePasswordAuthenticationFilter 將重新注入的 Authentication 對(duì)象填充到 SecurityContext 中。

指紋登錄實(shí)踐

指紋登錄和用戶名密碼登錄區(qū)別很小,只是將密碼換成了指紋特征值。下面采用 Spring Security 推薦寫法 Filter-AuthenticationProvider 的形式來定義相關(guān)組件以實(shí)現(xiàn)指紋登錄。完整的項(xiàng)目地址:https://github.com/springAppl/rachel。

FingerPrintToken

FingerPrintToken 增加 name 和 fingerPrint 字段,分別代表用戶名和指紋特征值,如清單 16 所示:

清單 16. FingerPrintToken 函數(shù)簽名

public class FingerPrintToken implements Authentication {
    private String name;  
    private String fingerPrint;
    ......
}

FingerPrintFilter

FingerPrintFilter 處理指紋登錄請(qǐng)求,調(diào)用 AuthenticationManager 進(jìn)行驗(yàn)證,驗(yàn)證通過后調(diào)用 SecurityContextHolder 將重新注入的 Authentication 填充到 SecurityContext 中,如清單 17 所示:

清單 17. doFilter 函數(shù)簽名

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
FilterChain filterChain) throws IOException, ServletException {
    if (Objects.equals(httpServletRequest.getRequestURI(), "/api/finger-print")) {
        // 調(diào)用 AuthenticationManager, 并填充 SecurityContext
    }
}

FingerPrintProvider

FingerPrintProvider 負(fù)責(zé)處理 FingerPrintToken,需要在 supports 函數(shù)中支持處理 FingerPrintToken。authenticate 函數(shù)負(fù)責(zé) UserDetails 獲取,指紋校驗(yàn),F(xiàn)ingerPrintToken 的重新注入。

FingerPrintUserDetails

FingerPrintUserDetails 繼承 User 并實(shí)現(xiàn) UserDetails 的方法,應(yīng)用的用戶信息可以加載到 Spring Security 中使用。

FingerPrintUserDetailsService

FingerPrintUserDetailsService 獲取 FingerUserDetails。通過 UserDao 查找到 User,并將 User 轉(zhuǎn)換為 Spring Security 可識(shí)別 UserDetails。

SecurityConfig

SecurityConfig 繼承 WebSecurityConfigurerAdapter,需要定義 Spring Security 配置類。Spring Security 的配置不是本文的重點(diǎn),配置時(shí)只需要注意以下幾點(diǎn):

  1. 將 FingerPrintFilter、FingerPrintProvider 添加進(jìn)去。
  2. 將 FingerPrintFilter 的執(zhí)行順序放置在 SecurityContextPersistenceFilter 之后即可。Spring Security 維護(hù)了一個(gè) Filter 的 list,因此每個(gè) Filter 是有順序的。
  3. 將 "/api/test" 請(qǐng)求設(shè)置為用戶驗(yàn)證成功后才允許方問。

配置代碼在 configure 函數(shù)中,如清單 18 所示:

清單 18. configure 函數(shù)

protected void configure(HttpSecurity http) throws Exception {
    http
       .userDetailsService(userDetailsService())
       .addFilterAfter(fingerPrintFilter(), SecurityContextPersistenceFilter.class)
       .authenticationProvider(fingerPrintProvider())
       .authorizeRequests()
       .mvcMatchers(HttpMethod.GET, "/api/test").authenticated()
}

總結(jié)

在 Web 時(shí)代,用戶和應(yīng)用的耦合度越來越高,應(yīng)用中存儲(chǔ)了大量用戶的私密信息。隨著各種用戶信息泄露事件的爆發(fā),安全成為了 Web 應(yīng)用重要的一個(gè)環(huán)。Spring Security 由于其強(qiáng)大的功能和 Spring Framework 的高度集成,贏得了開發(fā)人員的青睞。本文對(duì) Spring Security 的架構(gòu)設(shè)計(jì)與核心組件進(jìn)行了深入淺出的介紹,分析了 Spring Security 在 Web 應(yīng)用的集成方式,并展示了一個(gè)指紋登錄的實(shí)例。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java使用MyBatis框架分頁的5種方式

    Java使用MyBatis框架分頁的5種方式

    這篇文章主要為大家詳細(xì)介紹了Java使用MyBatis框架分頁的5種方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 基于kafka實(shí)現(xiàn)Spring Cloud Bus消息總線

    基于kafka實(shí)現(xiàn)Spring Cloud Bus消息總線

    消息總線是一種通信工具,可以在機(jī)器之間互相傳輸消息、文件等,這篇文章主要介紹了如何利用kafka實(shí)現(xiàn)SpringCloud Bus消息總線,感興趣的可以學(xué)習(xí)一下
    2022-04-04
  • 快速入手IntelliJ IDEA基本配置

    快速入手IntelliJ IDEA基本配置

    IntelliJ IDEA是java編程語言開發(fā)的集成環(huán)境,本篇主要介紹了對(duì)它的安裝、配置maven倉庫、調(diào)試方法、常用的插件推薦、快捷鍵大全與常用快捷鍵說明,感興趣的朋友一起看看吧
    2021-10-10
  • 重寫Java中的equals方法介紹

    重寫Java中的equals方法介紹

    這篇文章主要介紹了重寫Java中的equals方法介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java多線程事務(wù)回滾@Transactional失效處理方案

    Java多線程事務(wù)回滾@Transactional失效處理方案

    這篇文章主要介紹了Java多線程事務(wù)回滾@Transactional失效處理方案,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • 解析SpringSecurity自定義登錄驗(yàn)證成功與失敗的結(jié)果處理問題

    解析SpringSecurity自定義登錄驗(yàn)證成功與失敗的結(jié)果處理問題

    這篇文章主要介紹了SpringSecurity系列之自定義登錄驗(yàn)證成功與失敗的結(jié)果處理問題,本文通過實(shí)例給大家講解的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • @PropertySource 無法讀取配置文件的屬性值解決方案

    @PropertySource 無法讀取配置文件的屬性值解決方案

    這篇文章主要介紹了@PropertySource 無法讀取配置文件的屬性值解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java實(shí)現(xiàn)簡單圖形界面計(jì)算器

    Java實(shí)現(xiàn)簡單圖形界面計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡單圖形界面計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Java 讀取excel 文件流代碼實(shí)例

    Java 讀取excel 文件流代碼實(shí)例

    這篇文章主要介紹了Java 讀取excel 文件流代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • netty中的ByteBuf源碼詳解

    netty中的ByteBuf源碼詳解

    這篇文章主要介紹了netty中的ByteBuf源碼詳解,ByteBuf,顧名思義,就是字節(jié)緩沖區(qū),是Netty中非常重要的一個(gè)組件,某些場景下性能不是太好,netty開發(fā)團(tuán)隊(duì)重新設(shè)計(jì)了ByteBuf用以替代原生ByteBuffer,需要的朋友可以參考下
    2023-11-11

最新評(píng)論