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

Spring security自定義用戶認(rèn)證流程詳解

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

1.自定義登錄頁面

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

  注意:springboot項(xiàng)目默認(rèn)可以訪問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()
        // 添加一個(gè)url匹配器,如果匹配到login.html,就授權(quán)
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        // 關(guān)閉spring security默認(rèn)的防csrf攻擊
        .csrf().disable();
  }

(3)測試

(4)存在的問題

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

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

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

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

自定義Controller

@Slf4j
@RestController
public class LoginController {

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

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

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

  /**
   * 用戶身份認(rèn)證方法
   */
  @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("請(qǐng)求是:" + targetUrl);
      // 如果請(qǐng)求是以html結(jié)尾
      if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) {
        redirectStrategy.sendRedirect(request, response, standardLoginPage);
      }
    }
    return new ResponseData("該請(qǐng)求需要登錄,js拿到我的響應(yīng)數(shù)據(jù)后,是否需要跳轉(zhuǎn)到登錄頁面你自己看著辦吧?");
  }
}

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

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

這樣子就行了!??! 

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

(1)實(shí)現(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()
        // 先進(jìn)controller中去
        .loginPage("/user/auth")
        // 指定自定義登錄頁面
        .loginPage("/login.html")
        // 登錄url
        .loginProcessingUrl("/auth/login")
        .successHandler(myAuthenticationSuccessHandler)
        .and()
        .authorizeRequests()
        // 該controller需要授權(quán)
        .antMatchers("/user/auth").permitAll()
        // 添加一個(gè)url匹配器,如果匹配到login.html,就授權(quán)
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        // 關(guān)閉spring security默認(rèn)的防csrf攻擊
        .csrf().disable();
  }

(3)測試

說明:authentication對(duì)象中包含的信息,會(huì)因?yàn)榈卿浄绞降牟煌l(fā)生改變

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

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

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

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

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

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

  /**
   * 配置的登錄方式
   */
//  @Value("${xxx:默認(rèn)方式}")
  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 { // 否則就使用默認(rèn)的跳轉(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:默認(rèn)方式}")
  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 { // 否則就使用默認(rèn)的跳轉(zhuǎn)方式,跳轉(zhuǎn)到一個(gè)錯(cuò)誤頁面
      super.onAuthenticationFailure(request,response,exception);
    }
  }
}
@Autowired
  private MySimpleUrlAuthenticationFailureHandler mySimpleUrlAuthenticationFailureHandler;
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        // 先進(jìn)controller中去
        .loginPage("/user/auth")
        // 指定自定義登錄頁面
        .loginPage("/login.html")
        // 登錄url
        .loginProcessingUrl("/auth/login")
        .successHandler(myAuthenticationSuccessHandler)
        .failureHandler(mySimpleUrlAuthenticationFailureHandler)
        .and()
        .authorizeRequests()
        // 該controller需要授權(quán)
        .antMatchers("/user/auth").permitAll()
        // 添加一個(gè)url匹配器,如果匹配到login.html,就授權(quán)
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        // 關(guān)閉spring security默認(rèn)的防csrf攻擊
        .csrf().disable();
  }

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

相關(guān)文章

  • springboot如何整合elasticsearch

    springboot如何整合elasticsearch

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

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

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

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

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

    Spring中Bean對(duì)象的定義、注冊(cè)和獲取流程分析

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

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

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

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

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

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

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

    Mybatis動(dòng)態(tài)SQL foreach標(biāo)簽用法實(shí)例

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

    使用Feign遠(yuǎn)程調(diào)用時(shí),序列化對(duì)象失敗的解決

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

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

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

最新評(píng)論

桓仁| 闵行区| 翁源县| 奇台县| 孟州市| 杭锦旗| 武陟县| 油尖旺区| 盐津县| 收藏| 文化| 济阳县| 巴塘县| 潮州市| 灵丘县| 浮梁县| 西畴县| 那曲县| 磴口县| 思南县| 西吉县| 伊春市| 清苑县| 白水县| 和硕县| 邵阳县| 策勒县| 历史| 浪卡子县| 日喀则市| 儋州市| 广宗县| 阳泉市| 金川县| 邵阳县| 河西区| 白河县| 富裕县| 尖扎县| 开江县| 洛阳市|