最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言

Java 開(kāi)發(fā)人員在解決 Web 應(yīng)用安全相關(guān)的問(wèn)題時(shí),通常會(huì)采用兩個(gè)非常流行的安全框架,Shiro 和 Spring Security。Shiro 配置簡(jiǎn)單,上手快,滿足一般應(yīng)用的安全需求,但是功能相對(duì)單一。Spring Security 安全粒度細(xì),與 Spring Framework 無(wú)縫集成,滿足絕大多數(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)用中的開(kāi)發(fā)方式,最后以一個(gè)指紋登錄的實(shí)例收尾。

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

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

SecurityContext

SecurityContext 即安全上下文,關(guān)聯(lián)當(dāng)前用戶的安全信息。用戶通過(guò) 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)用(音樂(lè)播放器,游戲等等),用戶登錄完畢,在軟件的整個(gè)生命周期中只有當(dāng)前登錄用戶,面對(duì)這種情況 SecurityContextHolder 更適合采用 MODE_GLOBAL 模式,SecurityContext 相當(dāng)于存儲(chǔ)在應(yīng)用的進(jìn)程中,SecurityContext 在所有線程中都相同。

Authentication

Authentication 即驗(yàn)證,表明當(dāng)前用戶是誰(shuí)。什么是驗(yàn)證,比如一組用戶名和密碼就是驗(yàn)證,當(dāng)然錯(cuò)誤的用戶名和密碼也是驗(yàn)證,只不過(guò) 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)類(lèi)都會(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)緯度之類(lèi)的信息。通過(guò)驗(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: 賬戶是否過(guò)期。
  • isAccountNonLocked: 賬戶是否被鎖定。
  • isCredentialsNonExpired: 密碼是否過(guò)期。
  • isEnabled: 賬戶是否可用。

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

AuthenticationManager

AuthenticationManager 負(fù)責(zé)校驗(yàn) Authentication 對(duì)象。在 AuthenticationManager 的 authenticate 函數(shù)中,開(kāi)發(fā)人員實(shí)現(xiàn)對(duì) Authentication 的校驗(yàn)邏輯。如果 authenticate 函數(shù)校驗(yàn)通過(guò),正常返回一個(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í)別到 "你是誰(shuí)"。

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

下面采用 Spring Security 的核心組件寫(xiě)一個(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)證信息傳遞過(guò)來(lái),驗(yàn)證通過(guò),將驗(yàn)證信息存儲(chǔ)到 SecurityContext 中;驗(yàn)證失敗,做出相應(yīng)的處理。

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

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

Spring Security 最簡(jiǎn)登錄實(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 來(lái)集成已存在的登錄邏輯,真正和 Spring Security 關(guān)聯(lián)的代碼只有短短 3 行。驗(yàn)證邏輯可以不經(jīng)過(guò) AuthenticationManager,真正需要做的就是把經(jīng)過(guò)驗(yàn)證的用戶信息注入到 Authentication 中,并將 Authentication 填充到 SecurityContext 中。在實(shí)際情況中,登錄邏輯的確可以這樣寫(xiě),尤其是已經(jīng)存在登錄邏輯的時(shí)候,通常會(huì)這樣寫(xiě)。這樣寫(xiě)雖然方便,但是不符合 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è)很常見(jiàn)的問(wèn)題是:Spring Security 在 Web 中的入口是哪里?答案是 Filter。Spring Security 在 Filter 中創(chuàng)建 Authentication 對(duì)象,并調(diào)用 AuthenticationManager 進(jìn)行校驗(yàn)。Spring Security 選擇 Filter,而沒(méi)有采用上文中 Controller 的方式有以下優(yōu)點(diǎn)。Spring Security 依賴 J2EE 標(biāo)準(zhǔn),無(wú)需依賴特定的 MVC 框架。另一方面 Spring MVC 通過(guò) Servlet 做請(qǐng)求轉(zhuǎn)發(fā),如果 Spring Security 采用 Servlet,那么 Spring Security 和 Spring MVC 的集成會(huì)存在問(wèn)題。FilterChain 維護(hù)了很多 Filter,每個(gè) Filter 都有自己的功能,因此在 Spring Security 中添加新功能時(shí),推薦通過(guò) Filter 的方式來(lái)實(shí)現(xiàn)。

ProviderManager

ProviderManager 是 AuthenticationManager 的實(shí)現(xiàn)類(lèi)。ProviderManager 并沒(méi)有實(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)證方式的代碼都寫(xiě)在 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)來(lái)時(shí),ProviderManager 通過(guò) supports 函數(shù)查找支持校驗(yàn)的 AuthenticationProvider。如果沒(méi)有找到支持的 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)證邏輯需要寫(xiě)在對(duì)應(yīng) AuthenticationProvider 中的 authenticate 函數(shù)中。驗(yàn)證通過(guò)返回一個(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

下面以用戶名密碼登錄為例來(lái)梳理 Spring Security 在 Web 中的認(rèn)證流程。上文提到 Spring Security 是以 Filter 來(lái)作為校驗(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 父類(lèi) 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)類(lèi) ProviderManager 并沒(méi)有實(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, 如果緩存中沒(méi)有獲取到,調(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 非常簡(jiǎn)單,只有一個(gè) loadUserByUserName 函數(shù),函數(shù)參數(shù)雖然名為 username,但只要是用戶的唯一標(biāo)識(shí)符即可。下面是基于數(shù)據(jù)庫(kù)存儲(chǔ)的簡(jiǎn)單示例, 如清單 14 所示:

清單 14. CustomUserDetailsService 類(lèi)簽名

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ì)象。如果沒(méi)有找到 User 對(duì)象,需要拋出 UsernameNotFoundException 異常。

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

DaoAuthenticationProvider 對(duì) Authentication 對(duì)象的重新注入通過(guò)調(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è)流程,簡(jiǎn)言之:

  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)通過(guò)后返回重新注入的 Authentication 對(duì)象。
  4. UsernamePasswordAuthenticationFilter 將重新注入的 Authentication 對(duì)象填充到 SecurityContext 中。

指紋登錄實(shí)踐

指紋登錄和用戶名密碼登錄區(qū)別很小,只是將密碼換成了指紋特征值。下面采用 Spring Security 推薦寫(xiě)法 Filter-AuthenticationProvider 的形式來(lái)定義相關(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)證通過(guò)后調(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。通過(guò) UserDao 查找到 User,并將 User 轉(zhuǎn)換為 Spring Security 可識(shí)別 UserDetails。

SecurityConfig

SecurityConfig 繼承 WebSecurityConfigurerAdapter,需要定義 Spring Security 配置類(lèi)。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)證成功后才允許方問(wè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)用的耦合度越來(lái)越高,應(yīng)用中存儲(chǔ)了大量用戶的私密信息。隨著各種用戶信息泄露事件的爆發(fā),安全成為了 Web 應(yīng)用重要的一個(gè)環(huán)。Spring Security 由于其強(qiáng)大的功能和 Spring Framework 的高度集成,贏得了開(kāi)發(fā)人員的青睞。本文對(duì) Spring Security 的架構(gòu)設(shè)計(jì)與核心組件進(jìn)行了深入淺出的介紹,分析了 Spring Security 在 Web 應(yīng)用的集成方式,并展示了一個(gè)指紋登錄的實(shí)例。

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

相關(guān)文章

  • Spring?Data?Jpa框架最佳實(shí)踐示例

    Spring?Data?Jpa框架最佳實(shí)踐示例

    這篇文章主要為大家介紹了Spring?Data?Jpa框架最佳實(shí)踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-02-02
  • MyBatis-Plus詳解(環(huán)境搭建、關(guān)聯(lián)操作)

    MyBatis-Plus詳解(環(huán)境搭建、關(guān)聯(lián)操作)

    MyBatis-Plus 是一個(gè) MyBatis 的增強(qiáng)工具,在 MyBatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開(kāi)發(fā)、提高效率而生,今天通過(guò)本文給大家介紹MyBatis-Plus環(huán)境搭建及關(guān)聯(lián)操作,需要的朋友參考下吧
    2022-09-09
  • 詳解Springboot事務(wù)管理

    詳解Springboot事務(wù)管理

    本篇文章主要介紹了詳解Springboot事務(wù)管理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • Nacos注冊(cè)中心的幾種調(diào)用方式詳解

    Nacos注冊(cè)中心的幾種調(diào)用方式詳解

    Spring Cloud Alibaba Nacos 作為近幾年最熱門(mén)的注冊(cè)中心和配置中心,也被國(guó)內(nèi)無(wú)數(shù)公司所使用,本文就來(lái)看下 Nacos 作為注冊(cè)中心時(shí),調(diào)用它的接口有幾種方式
    2023-10-10
  • java拋出異常與finally實(shí)例解析

    java拋出異常與finally實(shí)例解析

    這篇文章主要介紹了java拋出異常與finally實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • SpringBoot實(shí)現(xiàn)對(duì)Http接口進(jìn)行監(jiān)控的代碼

    SpringBoot實(shí)現(xiàn)對(duì)Http接口進(jìn)行監(jiān)控的代碼

    Spring Boot Actuator是Spring Boot提供的一個(gè)模塊,用于監(jiān)控和管理Spring Boot應(yīng)用程序的運(yùn)行時(shí)信息,本文將介紹一下Spring Boot Actuator以及代碼示例,以及如何進(jìn)行接口請(qǐng)求監(jiān)控,需要的朋友可以參考下
    2024-07-07
  • springboot內(nèi)置tomcat之NIO處理流程一覽

    springboot內(nèi)置tomcat之NIO處理流程一覽

    這篇文章主要介紹了springboot內(nèi)置tomcat之NIO處理流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java Web三層架構(gòu)的配置詳解

    Java Web三層架構(gòu)的配置詳解

    這篇文章主要介紹了Java Web三層架構(gòu)的配置方法,需要的朋友可以參考下
    2014-10-10
  • 教你怎么用IDEA快速生成注釋文檔

    教你怎么用IDEA快速生成注釋文檔

    這篇文章主要介紹了教你怎么用IDEA快速生成注釋文檔,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)IDEA操作的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • 一文看懂 Spring Aware 接口功能

    一文看懂 Spring Aware 接口功能

    Aware接口是一個(gè)空接口,可以理解為是一個(gè)標(biāo)記接口,方便在一個(gè)統(tǒng)一的方法(AbstractAutowireCapableBeanFactory.invokeAwareMethods)中進(jìn)行判斷處理賦值,在子接口寫(xiě)出各自的set方法,這篇文章主要介紹了一文看懂 Spring Aware 接口功能,需要的朋友可以參考下
    2024-12-12

最新評(píng)論

关岭| 临桂县| 澄迈县| 建德市| 永修县| 景泰县| 辛集市| 屏东县| 北票市| 黑龙江省| 涪陵区| 石柱| 南投市| 阿合奇县| 天水市| 滨海县| 德令哈市| 金阳县| 景泰县| 玉环县| 都兰县| 永清县| 沾益县| 永丰县| 昌宁县| 伊吾县| 称多县| 正宁县| 阿拉善右旗| 苏州市| 保康县| 仁化县| 洪江市| 湖南省| 连平县| 金寨县| 辉南县| 天津市| 调兵山市| 马鞍山市| 额尔古纳市|