国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【深入淺出Spring Security(五)】自定義過濾器進行前后端登錄認證

這篇具有很好參考價值的文章主要介紹了【深入淺出Spring Security(五)】自定義過濾器進行前后端登錄認證。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、自定義過濾器

在【深入淺出Spring Security(二)】Spring Security的實現(xiàn)原理 中小編闡述了默認加載的過濾器,里面有些過濾器有時并不能滿足開發(fā)中的實際需求,這個時候就需要我們自定義過濾器,然后填入或者替換掉原先存在的過濾器。

首先闡述一下添加過濾器的四個方法(都是HttpSecurity中的),下面方法第一個參數(shù)都是要加入的過濾器,第二個參數(shù)是針對已存在過濾器的Class對象:

  • addFilterAt(filter,atFilter):這個相當于線性表的插入操作,把 filter 插入在 atFilter 的位置上。
  • addFilterBefore(filter,atFilter):這個是在 atFilter 前插入一個 filter 過濾器;
  • addFilterAfter(filter,atFilter):這個顧名思義是在 atFilter 后插入一個 filter 過濾器;

自定義登錄認證過濾器

在 【深入淺出Spring Security(三)】默認登錄認證的實現(xiàn)原理 中小編述說過默認的用戶登錄認證是走的 UsernamePasswordAuthenticationFilter,它是通過表單數(shù)據(jù)傳輸?shù)姆绞?,然后通過 request.getParameter(username/password) 的方式獲取用戶名密碼進行認證的。但在前后端分離中,當提交登錄數(shù)據(jù)給后端是 JSON 格式的話,咱就要自定義過濾器去處理這個數(shù)據(jù)獲取用戶名和密碼進行認證了。

既然是換了一種登錄認證過濾器,而且用于前后端分離,咱就可以把一些不必要的默認過濾器給pass掉。當我們調(diào)用 HttpSecurity 中的 formLogin() 方法的時候,會幫我們加載如下圈到的三個過濾器。

  1. UsernamePasswordAuthenticationFilter:負責表單認證的;
  2. DefaultLoginPageGeneratingFilter:提供登錄界面的;
  3. DefaultLogoutPageGeneratingFilter:提供注銷界面的;

【深入淺出Spring Security(五)】自定義過濾器進行前后端登錄認證
那當我們在自定義 SecurityFilterChain 的時候不去調(diào)用 formLogin 方法的話,那這三個過濾器就相當于被我們 pass 掉了。

自定義 LoginFilter

既然咱要去實現(xiàn)一個 JSON 數(shù)據(jù)格式的認證,首先得先對請求進行一些判斷:

  1. 請求方式應(yīng)該是 POST 方式;
  2. 請求發(fā)來的數(shù)據(jù)應(yīng)該是 JSON 格式的。

不滿足這些的話,應(yīng)該去采取默認配置的登錄認證。

實現(xiàn)方式很簡單:

咱去繼承 UsernamePasswordAuthenticationFilter 重寫 attemptAuthentication 方法,實現(xiàn)自己的認證方式即可。

代碼如下:

public class LoginFilter extends UsernamePasswordAuthenticationFilter {

    public LoginFilter() {
    }

    public LoginFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }


    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {

        // 判斷請求方式是否是 POST 方式
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        // 然后判斷是否是 JSON 格式的數(shù)據(jù)
        if(request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {
            // 如果是的話就從 JSON 中取出用戶信息進行認證
            try {
                Map<String,String> userInfo = JSONObject.parseObject(request.getInputStream(), Map.class);
                String username = userInfo.get(getUsernameParameter());
                String password = userInfo.get(getPasswordParameter());
                // 封裝成Authentication
                UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,
                        password);
                // 仿造父類去調(diào)用AuthenticationManager.authenticate認證就可以了
                setDetails(request,authRequest);
                return getAuthenticationManager().authenticate(authRequest);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        // 否則用父類的方式去認證
        return super.attemptAuthentication(request, response);
    }
}

配置 LoginFilter

這里使用的新版本的注入方式,而不是使用繼承 WebSecurityConfigurerAdapter 的方式,因為 WebSecurityConfigurerAdapter 已經(jīng)被棄用了,咱還是與時俱進吧。

@EnableWebSecurity
public class SecurityConfig {

    /**
     * 構(gòu)造基于內(nèi)存的數(shù)據(jù)源管理
     * @return  InMemoryUserDetailsManager
     */
    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager(){
        return new InMemoryUserDetailsManager(User
                .withUsername("admin")
                .password("{noop}123")
                .authorities("admin")
                .build()
        );
    }


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .logout()
                .logoutSuccessHandler(this::onAuthenticationSuccess)
                .logoutUrl("/api/auth/logout")
                .and()
                .addFilterAt(loginFilter(http), UsernamePasswordAuthenticationFilter.class) // 注意配置 filter 哦
                .csrf()
                .disable()
                .build();
    }

    /**
     * 自定義 AuthenticationManager
     * @param http
     * @return  AuthenticationManager
     * @throws Exception
     */
    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        return http.
                getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(inMemoryUserDetailsManager())
                .and()
                .build();
    }

    @Bean
    public LoginFilter loginFilter(HttpSecurity http) throws Exception {
        LoginFilter loginFilter = new LoginFilter(authenticationManager(http));
        // 自定義 JSON 的 key
        loginFilter.setUsernameParameter("username");
        loginFilter.setPasswordParameter("password");
        // 自定義接收的url,默認是login
        // 此過濾器的doFilter是在AbstractAuthenticationProcessingFilter,在那里進行的url是否符合的判定
        loginFilter.setFilterProcessesUrl("/api/auth/login");
        // 設(shè)置login成功返回的JSON數(shù)據(jù)
        loginFilter.setAuthenticationSuccessHandler(this::onAuthenticationSuccess);
        // 設(shè)置login失敗返回的JSON數(shù)據(jù)
        loginFilter.setAuthenticationFailureHandler(this::onAuthenticationFailure);
        return loginFilter;
    }

    @Resource
    private ObjectMapper objectMapper;
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException{
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        if(request.getRequestURI().endsWith("/login"))
            out.write(objectMapper.writeValueAsString(JsonData.success("登錄成功")));
        else if(request.getRequestURI().endsWith("/logout"))
            out.write(objectMapper.writeValueAsString(JsonData.success("注銷成功")));
        out.close();
    }

    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException{
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.write(objectMapper.writeValueAsString(JsonData.failure(401,exception.getMessage())));
        out.close();
    }

}

測試

【深入淺出Spring Security(五)】自定義過濾器進行前后端登錄認證文章來源地址http://www.zghlxwxcb.cn/news/detail-475301.html

二、總結(jié)

  1. HttpSecurity 中可以用來添加過濾器的三個方法
  • addFilterAt(filter,atFilter):這個相當于線性表的插入操作,把 filter 插入在 atFilter 的位置上。
  • addFilterBefore(filter,atFilter):這個是在 atFilter 前插入一個 filter 過濾器;
  • addFilterAfter(filter,atFilter):這個顧名思義是在 atFilter 后插入一個 filter 過濾器;
  1. 自定義登錄認證可以去繼承 UsernamePasswordAuthenticationFilter 過濾器重寫 attemptAuthentication 方法進行自定義,然后再在自定義的 SecurityConfig 配置類里面去將它配置到 Spring 容器中,注意實例化它后一定要給它內(nèi)部屬性 AuthenticationManager 進行初始化賦值,不然交給Spring容器管理的時候會報錯;最后添加到過濾器鏈中。
  2. 不去調(diào)用 formLogin 方法,那下面三個過濾器在過濾器鏈 SecurityFilterChain 中。
    UsernamePasswordAuthenticationFilter:負責表單認證的;
    DefaultLoginPageGeneratingFilter:提供登錄界面的;
    DefaultLogoutPageGeneratingFilter:提供注銷界面的;

到了這里,關(guān)于【深入淺出Spring Security(五)】自定義過濾器進行前后端登錄認證的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【深入淺出 Spring Security(十三)】使用 JWT 進行前后端分離認證(附源碼)

    【深入淺出 Spring Security(十三)】使用 JWT 進行前后端分離認證(附源碼)

    JWT 全稱 Java web Token,在此所講述的是 JWT 用于身份認證,用服務(wù)器端生成的JWT去替代原始的Session認證,以提高安全性。 JWT本質(zhì)是一個Token令牌,是由三部分組成的字符串,分別是頭部(header)、載荷(payload)和簽名(signature)。頭部一般包含該 JWT 的基本信息,例如所使用的

    2024年02月12日
    瀏覽(25)
  • 【深入淺出 Spring Security(四)】登錄用戶數(shù)據(jù)的獲取,超詳細的源碼分析

    【深入淺出 Spring Security(四)】登錄用戶數(shù)據(jù)的獲取,超詳細的源碼分析

    在【深入淺出Spring Security(一)】Spring Security的整體架構(gòu) 中敘述過一個SecurityContextHolder 這個類。說在處理請求時,Spring Security 會先從 Session 中取出用戶登錄數(shù)據(jù),保存到 SecurityContextHolder 中,然后在請求處理完畢后,又會拿 SecurityContextHolder 中的數(shù)據(jù)保存到 Session 中,然后再

    2024年02月07日
    瀏覽(18)
  • 【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理

    【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理

    在 【深入淺出Spring Security(一)】Spring Security的整體架構(gòu) 中小編解釋過授權(quán)所用的三大組件,在此再解釋說明一下(三大組件具體指:ConfigAttribute、AccessDecisionManager(決策管理器)、AccessDecisionVoter(決策投票器)) ConfigAttribute 在 Spring Security 中,用戶請求一個資源(通常是

    2024年02月10日
    瀏覽(25)
  • Spring Security內(nèi)置過濾器詳解

    Spring Security內(nèi)置過濾器詳解

    相關(guān)文章: OAuth2的定義和運行流程 Spring Security OAuth實現(xiàn)Gitee快捷登錄 Spring Security OAuth實現(xiàn)GitHub快捷登錄 Spring Security的過濾器鏈機制 Spring Security OAuth Client配置加載源碼分析 根據(jù)前面的示例,我們已經(jīng)知道啟動時會加載18個過濾器,并且已經(jīng)知道了請求會匹配到DefaultSecurityF

    2024年02月05日
    瀏覽(26)
  • 【Spring Security系列】Spring Security 過濾器詳解與基于JDBC的認證實現(xiàn)

    【Spring Security系列】Spring Security 過濾器詳解與基于JDBC的認證實現(xiàn)

    上文說到,Spring Security它是一個強大的和高度可定制的身份驗證和訪問控制框架。它提供了一套豐富的功能,用于保護基于Spring的應(yīng)用程序。 上文又說到,在Spring Security中,過濾器(Filter)是一個重要的組件,用于處理身份驗證、授權(quán)和其他安全相關(guān)的任務(wù)。 Spring Security 的

    2024年04月22日
    瀏覽(40)
  • 深入淺出Spring AOP

    深入淺出Spring AOP

    第1章:引言 大家好,我是小黑,咱們今天要聊的是Java中Spring框架的AOP(面向切面編程)。對于程序員來說,理解AOP對于掌握Spring框架來說是超級關(guān)鍵的。它像是魔法一樣,能讓咱們在不改變原有代碼的情況下,給程序增加各種功能。 AOP不僅僅是一個編程范式,它更是一種思

    2024年01月20日
    瀏覽(28)
  • 【Spring Security】使用 OncePerRequestFilter 過濾器校驗登錄過期、請求日志等操作

    OncePerRequestFilter 是一個過濾器,每個請求都會執(zhí)行一次;一般開發(fā)中主要是做檢查是否已登錄、Token是否過期和授權(quán)等操作,而每個操作都是一個過濾器,下面演示一下。 檢查是否登錄過期過濾器 檢查是否登錄過期過濾器 End

    2024年02月10日
    瀏覽(18)
  • Spring Security 中的過濾器鏈是什么?它的作用是什么

    Spring Security 中的過濾器鏈是什么?它的作用是什么

    Spring Security是一個安全框架,它提供了強大的安全保護功能,可以幫助開發(fā)者更加方便地實現(xiàn)應(yīng)用程序的安全性。Spring Security中的過濾器鏈是其中一個非常重要的部分,它起到了非常重要的作用。本文將介紹什么是Spring Security中的過濾器鏈,以及它的作用和如何使用它。同時

    2024年02月06日
    瀏覽(22)
  • 【深入淺出】條件概率的鏈式法則:定義、公式與應(yīng)用

    【深入淺出】條件概率的鏈式法則:定義、公式與應(yīng)用

    在概率論的研究中,條件概率是一種非常重要的概念。當多個隨機事件發(fā)生時,我們有時需要考慮它們同時發(fā)生的概率。條件概率的鏈式法則就是一種用于計算多個隨機事件同時發(fā)生的概率的方法。本文將會介紹條件概率的鏈式法則的定義、公式以及應(yīng)用。 條件概率是指在已

    2024年02月08日
    瀏覽(24)
  • 深入淺出 Spring:核心概念和基本用法詳解

    深入淺出 Spring:核心概念和基本用法詳解

    個人主頁:17_Kevin-CSDN博客 收錄專欄;《Java》 在 Java 企業(yè)級應(yīng)用開發(fā)中,Spring 框架已經(jīng)成為了事實上的標準。它提供了一種輕量級的解決方案,使得開發(fā)者能夠更輕松地構(gòu)建靈活、可擴展的應(yīng)用程序。在本文中,我們將探討 Spring 框架的一些核心概念和基本用法,以此更好地

    2024年03月20日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包