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

Spring security自定義用戶認證流程詳解

 更新時間:2020年03月11日 14:42:01   作者:我太難了008  
這篇文章主要介紹了Spring security自定義用戶認證流程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

1.自定義登錄頁面

(1)首先在static目錄下面創(chuàng)建login.html

  注意:springboot項目默認可以訪問resources/resources,resources/staic,resources/public目錄下面的靜態(tài)文件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>登錄頁面</title>
</head>
<body>
<form action="/auth/login" method="post">
  用戶名:<input type="text" name="username">
  <br/>
  密&emsp;碼:<input type="password" name="password">
  <br/>
  <input type="submit" value="登錄">
</form>
</body>
</html>

(2)在spring securiy配置類中做如下配置

@Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        // 指定自定義登錄頁面
        .loginPage("/login.html")
        // 登錄url
        .loginProcessingUrl("/auth/login")
        .and()
        .authorizeRequests()
        // 添加一個url匹配器,如果匹配到login.html,就授權(quán)
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        // 關(guān)閉spring security默認的防csrf攻擊
        .csrf().disable();
  }

(3)測試

(4)存在的問題

<1>作為可以復(fù)用的登錄模塊,我們應(yīng)該提供個性化的登錄頁面,也就是說不能寫死只跳轉(zhuǎn)到login.html。

    此問題比較好解決,使用可配置的登錄頁面,默認使用login.html即可。

<2> 請求跳轉(zhuǎn)到login.html登錄頁面,貌似沒有什么問題,但作為restful風格的接口,一般響應(yīng)的都是json數(shù)據(jù)格式,尤其是app請求。

    解決思想:用戶發(fā)起數(shù)據(jù)請求 --> security判斷是否需要身份認證 ----->跳轉(zhuǎn)到一個自定義的controller方法 ------>在該方法內(nèi)判斷是否是html發(fā)起的請求,如果是,就跳轉(zhuǎn)到login.html,如果不是,響應(yīng)一個json格式的數(shù)據(jù),說明錯誤信息。

自定義Controller

@Slf4j
@RestController
public class LoginController {

  /**
   * 請求緩存
   */
  private RequestCache requestCache = new HttpSessionRequestCache();

  /**
   * 重定向工具類
   */
  private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

  /**
   * 如果配置的登錄頁就使用配置的登錄面,否則使用默認的登錄頁面
   */
//  @Value("${xxxx:defaultLoginPage}")
//  private String standardLoginPage;
  private String standardLoginPage = "/login.html"; // 登錄頁

  /**
   * 用戶身份認證方法
   */
  @GetMapping("/user/auth")
  @ResponseStatus(code = HttpStatus.UNAUTHORIZED) // 返回狀態(tài)
  public ResponseData login(HttpServletRequest request, HttpServletResponse response) throws IOException {
    SavedRequest savedRequest = requestCache.getRequest(request, response);
    if (savedRequest != null) {
      String targetUrl = savedRequest.getRedirectUrl();
      log.info("請求是:" + targetUrl);
      // 如果請求是以html結(jié)尾
      if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) {
        redirectStrategy.sendRedirect(request, response, standardLoginPage);
      }
    }
    return new ResponseData("該請求需要登錄,js拿到我的響應(yīng)數(shù)據(jù)后,是否需要跳轉(zhuǎn)到登錄頁面你自己看著辦吧?");
  }
}

spring security給該controller的login方法授權(quán)

@Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        // 先進controller中去
        .loginPage("/user/auth")
        // 指定自定義登錄頁面
        .loginPage("/login.html")
        // 登錄url
        .loginProcessingUrl("/auth/login")
        .and()
        .authorizeRequests()
        // 該controller需要授權(quán)
        .antMatchers("/user/auth").permitAll()
        // 添加一個url匹配器,如果匹配到login.html,就授權(quán)
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        // 關(guān)閉spring security默認的防csrf攻擊
        .csrf().disable();
  }

這樣子就行了?。?! 

2. 自定義登錄成功處理(返回json)

(1)實現(xiàn)AuthenticationSuccessHandler.java

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
  @Autowired
  private ObjectMapper objectMapper;
  /**
   * Called when a user has been successfully authenticated.
   * @param request
   * @param response
   * @param authentication
   * @throws IOException
   * @throws ServletException
   */
  @Override
  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    log.info("登錄成功?。?!");
    // 將登錄成功的信息寫到前端
    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
    response.getWriter().write(objectMapper.writeValueAsString(authentication));

  }
}

(2)修改security配置類

@Autowired
  private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        // 先進controller中去
        .loginPage("/user/auth")
        // 指定自定義登錄頁面
        .loginPage("/login.html")
        // 登錄url
        .loginProcessingUrl("/auth/login")
        .successHandler(myAuthenticationSuccessHandler)
        .and()
        .authorizeRequests()
        // 該controller需要授權(quán)
        .antMatchers("/user/auth").permitAll()
        // 添加一個url匹配器,如果匹配到login.html,就授權(quán)
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        // 關(guān)閉spring security默認的防csrf攻擊
        .csrf().disable();
  }

(3)測試

說明:authentication對象中包含的信息,會因為登錄方式的不同而發(fā)生改變

3.自定義登錄失敗處理(返回json)

  實現(xiàn)AuthenticationFailureHandler.java接口即可,跟登錄成敗處理配置一樣。

4.自定義登錄成功處理邏輯

 以上的登錄成功或失敗的返回的都是json,但是在某些情況下,就是存在著登錄成功或者失敗進行頁面跳轉(zhuǎn)(spring security默認的處理方式),那么這種返回json的方式就不合適了。所以,我們應(yīng)該做得更靈活,做成可配置的。

 對于登錄成功邏輯而言只需要對MyAuthenticationSuccessHandler.java稍做修改就行,代碼如下所示:

/**
 * SavedRequestAwareAuthenticationSuccessHandler spring security 默認的成功處理器
 */
@Slf4j
@Component
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
  @Autowired
  private ObjectMapper objectMapper;

  /**
   * 配置的登錄方式
   */
//  @Value("${xxx:默認方式}")
  private String loginType = "JSON";
  /**
   * Called when a user has been successfully authenticated.
   */
  @Override
  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    log.info("登錄成功?。?!");

    // 如果配置的登錄方式是JSON,就返回json數(shù)據(jù)
    if ("JSON".equals(loginType)) {
      // 將登錄成功的信息寫到前端
      response.setContentType(MediaType.APPLICATION_JSON_VALUE);
      response.getWriter().write(objectMapper.writeValueAsString(authentication));
    } else { // 否則就使用默認的跳轉(zhuǎn)方式
      super.onAuthenticationSuccess(request,response,authentication);
    }
  }
}

5.自定義登錄失敗處理邏輯

同登錄成功類似,具體代碼如下:

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@Component
public class MySimpleUrlAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
  @Autowired
  private ObjectMapper objectMapper;

  /**
   * 配置的登錄方式
   */
//  @Value("${xxx:默認方式}")
  private String loginType = "JSON";
  @Override
  public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
    log.info("登錄失?。。?!");

    // 如果配置的登錄方式是JSON,就返回json數(shù)據(jù)
    if ("JSON".equals(loginType)) {
      // 將登錄成功的信息寫到前端
      response.setStatus(HttpStatus.UNAUTHORIZED.value());
      response.setContentType(MediaType.APPLICATION_JSON_VALUE);
      response.getWriter().write(objectMapper.writeValueAsString(exception));
    } else { // 否則就使用默認的跳轉(zhuǎn)方式,跳轉(zhuǎn)到一個錯誤頁面
      super.onAuthenticationFailure(request,response,exception);
    }
  }
}
@Autowired
  private MySimpleUrlAuthenticationFailureHandler mySimpleUrlAuthenticationFailureHandler;
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        // 先進controller中去
        .loginPage("/user/auth")
        // 指定自定義登錄頁面
        .loginPage("/login.html")
        // 登錄url
        .loginProcessingUrl("/auth/login")
        .successHandler(myAuthenticationSuccessHandler)
        .failureHandler(mySimpleUrlAuthenticationFailureHandler)
        .and()
        .authorizeRequests()
        // 該controller需要授權(quán)
        .antMatchers("/user/auth").permitAll()
        // 添加一個url匹配器,如果匹配到login.html,就授權(quán)
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        // 關(guān)閉spring security默認的防csrf攻擊
        .csrf().disable();
  }

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

相關(guān)文章

  • springboot如何整合elasticsearch

    springboot如何整合elasticsearch

    這篇文章主要介紹了springboot如何整合elasticsearch問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式

    SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式

    這篇文章主要介紹了SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java 使用Axis調(diào)用WebService的示例代碼

    Java 使用Axis調(diào)用WebService的示例代碼

    這篇文章主要介紹了Java 使用Axis調(diào)用WebService的示例代碼,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-09-09
  • Spring中Bean對象的定義、注冊和獲取流程分析

    Spring中Bean對象的定義、注冊和獲取流程分析

    這篇文章主要介紹了Spring中Bean對象的定義、注冊和獲取流程分析,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • 詳解IDEA使用Maven項目不能加入本地Jar包的解決方法

    詳解IDEA使用Maven項目不能加入本地Jar包的解決方法

    這篇文章主要介紹了詳解IDEA使用Maven項目不能加入本地Jar包的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • java編譯后的文件出現(xiàn)xx$1.class的原因及解決方式

    java編譯后的文件出現(xiàn)xx$1.class的原因及解決方式

    這篇文章主要介紹了java編譯后的文件出現(xiàn)xx$1.class的原因及解決方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • java實現(xiàn)簡單的圖書借閱系統(tǒng)

    java實現(xiàn)簡單的圖書借閱系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡單的圖書借閱系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Mybatis動態(tài)SQL foreach標簽用法實例

    Mybatis動態(tài)SQL foreach標簽用法實例

    這篇文章主要介紹了Mybatis動態(tài)SQL foreach標簽用法實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • 使用Feign遠程調(diào)用時,序列化對象失敗的解決

    使用Feign遠程調(diào)用時,序列化對象失敗的解決

    這篇文章主要介紹了使用Feign遠程調(diào)用時,序列化對象失敗的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 淺談java獲取服務(wù)器基本信息

    淺談java獲取服務(wù)器基本信息

    這篇文章主要介紹了java獲取服務(wù)器基本信息,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03

最新評論

明水县| 建德市| 潮安县| 濉溪县| 吉安县| 左贡县| 五华县| 吉木萨尔县| 武邑县| 旌德县| 布尔津县| 濮阳市| 怀远县| 治县。| 德格县| 渝北区| 林芝县| 濮阳县| 文安县| 邓州市| 平罗县| 海门市| 新巴尔虎右旗| 内黄县| 板桥市| 莲花县| 揭西县| 马鞍山市| 湄潭县| 勐海县| 玛沁县| 离岛区| 鲁山县| 荣成市| 平陆县| 荣昌县| 漾濞| 九龙县| 京山县| 文化| 尉犁县|