Spring Cloud微服務安全實戰_3-4_API安全機制之認證


 認證:登錄和認證是 兩個概念,比如你兩周、一個月,可能只登錄了一次,但認證卻是每次訪問都要經過的步驟。

對於圖中的認證不成功,也要繼續處理,這個我覺得得看業務,比如管理系統,不登錄就不讓你訪問,但對於比如電商的商品信息,不登錄,也是可以訪問的。

一、寫一個用戶注冊服務

數據庫user表:

 User類:

 

 

 單一職責原則:用戶注冊服務,得新建一個UserInfo類,用來接收前端傳過來的注冊用戶信息,而最好不要使用User類直接接收。

新增方法,可以將UserInfo返回,前端可以做相應的展示。

Controller:

Service:

 

 

 PostMan調用,成功。

 二、HttpBasic認證

在HTTP協議進行通信的過程中,HTTP協議定義了基本認證過程以允許HTTP服務器對WEB瀏覽器進行用戶身份證的方法,當一個客戶端向HTTP服務器進行數據請求時,如果客戶端未被認證,則HTTP服務器將通過基本認證過程對客戶端的用戶名及密碼進行驗證,以決定用戶是否合法。

具體做法是,將用戶名、密碼用:號隔開,然后base64編碼,放在請求頭的Authorization字段里,值是Basic  base64編碼的字符串

RequestHeader 

    Authorization:Basic Base64(用戶名:密碼)

比較簡單,但是安全性不高。

下面寫一個HttpBasic過濾器,做認證

package com.nb.security.filter;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.nb.security.entity.User;
import com.nb.security.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 處理httpbasic認證過濾器
 * httpbasic:請求頭,即Authorization:Basic 加密字符串
 * 加密字符串為Base64編碼的用戶名:密碼字符串
 * Authorization  Basic bGh5OmxoeWFwcA==
 * 在SpringBoot里,任何實現了Filter接口的類,SpringBoot會自動把它加到web應用的過濾器鏈里,只要聲名為Component就行了
 */
//@Order(2)
@Component
public class BasicAuthorizationFilter extends OncePerRequestFilter {//確保在一次請求只通過一次filter,並不是所有的container都像我們期望的只過濾一次,servlet版本不同,表現也不同

    @Autowired
    private IUserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        System.err.println("++++認證++++");
        String authHeader = request.getHeader("Authorization");
        if (StringUtils.isNotBlank(authHeader)) {
            String token64 = StringUtils.substringAfter(authHeader, "Basic ");
            String token = new String(Base64Utils.decodeFromString(token64));//base64解碼
            String[] items = StringUtils.splitByWholeSeparatorPreserveAllTokens(token, ":");//分隔用戶名和密碼
            String username = items[0];
            String password = items[1];
            User user = userService.getOne(new QueryWrapper<User>().eq("username", username));
            if (user != null && StringUtils.equals(user.getPassword(), password)) {
                //將用戶信息放到request
                request.setAttribute("user", user);
            }
        }

        //繼續執行其他過濾器
        filterChain.doFilter(request, response);
    }
}

Controller:

 

 Postman訪問,在請求頭輸入數據庫已存在的username、password:

 

 錯誤的訪問

 

 httpbasic至此完成,問題:不能每個請求都帶上用戶名密碼吧?

+++++++++++++++++++++++++++++分割線++++++++++++++++++++++++++++++

小結

本篇說了 httpbasic過濾器進行HTTPBasic認證

代碼:https://github.com/lhy1234/springcloud-security/tree/master/nb-user-api


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM