成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

SpringBoot使用Filter實(shí)現(xiàn)簽名認(rèn)證鑒權(quán)的示例代碼

瀏覽:3日期:2023-03-15 09:49:39
情景說明

鑒權(quán),有很多方案,如:SpringSecurity、Shiro、攔截器、過濾器等等。如果只是對(duì)一些URL進(jìn)行認(rèn)證鑒權(quán)的話,我們完全沒必要引入SpringSecurity或Shiro等框架,使用攔截器或過濾器就足以實(shí)現(xiàn)需求。本文介紹如何使用過濾器Filter實(shí)現(xiàn)URL簽名認(rèn)證鑒權(quán)。

本人測(cè)試軟硬件環(huán)境:Windows10、Eclipse、SpringBoot、JDK1.8

準(zhǔn)備工作 第一步:在pom.xml中引入相關(guān)依賴

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency> <!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> <!-- devtools --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency> <!-- org.apache.commons.codec --><!-- MD5加密的依賴 --><dependency><groupId>org.apache.directory.studio</groupId><artifactId>org.apache.commons.codec</artifactId><version>1.8</version></dependency></dependencies>第二步:在系統(tǒng)配置文件application.properties中配置相關(guān)參數(shù),一會(huì)兒代碼中需要用到

# ip白名單(多個(gè)使用逗號(hào)分隔)permitted-ips = 169.254.205.177, 169.254.133.33, 10.8.109.31, 0:0:0:0:0:0:0:1# secretsecret = JustryDeng第三步:準(zhǔn)備獲取客戶端IP的工具類

import java.net.InetAddress;import java.net.UnknownHostException; import javax.servlet.http.HttpServletRequest; /** * 獲取發(fā)出request請(qǐng)求的客戶端ip * 注:如果是自己發(fā)出的請(qǐng)求,那么獲取的是自己的ip * 摘錄自https://blog.csdn.net/byy8023/article/details/80499038 * * 注意事項(xiàng): * 如果使用此工具,獲取到的不是客戶端的ip地址;而是虛擬機(jī)的ip地址(d當(dāng)客戶端安裝有VMware時(shí),可能出現(xiàn)此情況); * 那么需要在客戶端的[控制面板網(wǎng)絡(luò)和 Internet網(wǎng)絡(luò)連接]中禁用虛擬機(jī)網(wǎng)絡(luò)適配器 * * @author JustryDeng * @DATE 2018年9月10日 下午8:56:48 */public class IpUtil { public static String getIpAddr(HttpServletRequest request) {String ipAddress = null;try { ipAddress = request.getHeader('x-forwarded-for'); if (ipAddress == null || ipAddress.length() == 0 || 'unknown'.equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader('Proxy-Client-IP'); } if (ipAddress == null || ipAddress.length() == 0 || 'unknown'.equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader('WL-Proxy-Client-IP'); } if (ipAddress == null || ipAddress.length() == 0 || 'unknown'.equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();if (ipAddress.equals('127.0.0.1')) { // 根據(jù)網(wǎng)卡取本機(jī)配置的IP InetAddress inet = null; try {inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) {e.printStackTrace(); } ipAddress = inet.getHostAddress();} } // 對(duì)于通過多個(gè)代理的情況,第一個(gè)IP為客戶端真實(shí)IP,多個(gè)IP按照’,’分割 if (ipAddress != null && ipAddress.length() > 15) { // '***.***.***.***'.length() // = 15if (ipAddress.indexOf(',') > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(','));} }} catch (Exception e) { ipAddress='';}return ipAddress; }}第四步:準(zhǔn)備MD5加密工具類

import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import org.apache.commons.codec.binary.Hex; /** * MD5加密工具類 * * @author JustryDeng 參考自ShaoJJ的MD5加密工具類 * @DATE 2018年9月11日 下午2:14:21 */public class MDUtils { /** * 加密 * * @param origin * 要被加密的字符串 * @param charsetname * 加密字符,如UTF-8 * @DATE 2018年9月11日 下午2:12:51 */public static String MD5EncodeForHex(String origin, String charsetname) throws UnsupportedEncodingException, NoSuchAlgorithmException {return MD5EncodeForHex(origin.getBytes(charsetname));} public static String MD5EncodeForHex(byte[] origin) throws NoSuchAlgorithmException {return Hex.encodeHexString(digest('MD5', origin));} /** * 指定加密算法 * * @throws NoSuchAlgorithmException * @DATE 2018年9月11日 下午2:11:58 */private static byte[] digest(String algorithm, byte[] source) throws NoSuchAlgorithmException {MessageDigest md;md = MessageDigest.getInstance(algorithm);return md.digest(source);}}第五步:簡(jiǎn)單編寫一個(gè)Controller,方便后面的測(cè)試

SpringBoot使用Filter實(shí)現(xiàn)簽名認(rèn)證鑒權(quán)的示例代碼

SpringBoot使用Filter實(shí)現(xiàn)簽名認(rèn)證鑒權(quán) --- 邏輯代碼第一步:編寫過濾器

import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStreamReader; import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ReadListener;import javax.servlet.ServletException;import javax.servlet.ServletInputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value; import com.aspire.util.IpUtil;import com.aspire.util.MDUtils; /** * SpringBoot使用攔截器實(shí)現(xiàn)簽名認(rèn)證(鑒權(quán)) * @WebFilter注解指定要被過濾的URL * 一個(gè)URL會(huì)被多個(gè)過濾器過濾時(shí),還可以使用@Order(x)來指定過濾request的先后順序,x數(shù)字越小越先過濾 * * @author JustryDeng * @DATE 2018年9月11日 下午1:18:29 */@WebFilter(urlPatterns = { '/authen/test1', '/authen/test2', '/authen/test3'})public class SignAutheFilter implements Filter { private static Logger logger = LoggerFactory.getLogger(SignAutheFilter.class); @Value('${permitted-ips}')private String[] permittedIps; @Value('${secret}')private String secret;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {} @Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) res;try {String authorization = request.getHeader('Authorization');logger.info('getted Authorization is ---> ' + authorization);String[] info = authorization.split(','); // 獲取客戶端ipString ip = IpUtil.getIpAddr(request);logger.info('getted ip is ---> ' + ip);/* * 讀取請(qǐng)求體中的數(shù)據(jù)(字符串形式) * 注:由于同一個(gè)流不能讀取多次;如果在這里讀取了請(qǐng)求體中的數(shù)據(jù),那么@RequestBody中就不能讀取到了 * 會(huì)拋出異常并提示getReader() has already been called for this request * 解決辦法:先將讀取出來的流數(shù)據(jù)存起來作為一個(gè)常量屬性.然后每次讀的時(shí)候,都需要先將這個(gè)屬性值寫入,再讀出. *即每次獲取的其實(shí)是不同的流,但是獲取到的數(shù)據(jù)都是一樣的. *這里我們借助HttpServletRequestWrapper類來實(shí)現(xiàn) * 注:此方法涉及到流的讀寫、耗性能; */MyRequestWrapper mrw = new MyRequestWrapper(request);String bodyString = mrw.getBody();logger.info('getted requestbody data is ---> ' + bodyString);// 獲取幾個(gè)相關(guān)的字符// 由于authorization類似于// cardid='1234554321',timestamp='9897969594',signature='a69eae32a0ec746d5f6bf9bf9771ae36'// 這樣的,所以邏輯是下面這樣的int cardidIndex = info[0].indexOf('=') + 2;String cardid = info[0].substring(cardidIndex, info[0].length() - 1);logger.info('cardid is ---> ' + cardid);int timestampIndex = info[1].indexOf('=') + 2;String timestamp = info[1].substring(timestampIndex, info[1].length() - 1);int signatureIndex = info[2].indexOf('=') + 2;String signature = info[2].substring(signatureIndex, info[2].length() - 1);String tmptString = MDUtils.MD5EncodeForHex(timestamp + secret + bodyString, 'UTF-8').toUpperCase();logger.info('getted ciphertext is ---> {}, correct ciphertext is ---> {}',signature , tmptString); // 判斷該ip是否合法boolean containIp = false;for (String string : permittedIps) {if (string.equals(ip)) {containIp = true;break;}} // 再判斷Authorization內(nèi)容是否正確,進(jìn)而判斷是否最終放行boolean couldPass = containIp && tmptString.equals(signature);if (couldPass) {// 放行chain.doFilter(mrw, response);return;}response.sendError(403, 'Forbidden');} catch (Exception e) {logger.error('AxbAuthenticationFilter -> ' + e.getMessage(), e);response.sendError(403, 'Forbidden');}} @Overridepublic void destroy() { } } /** * 輔助類 ---> 變相使得可以多次通過(不同)流讀取相同數(shù)據(jù) * * @author JustryDeng * @DATE 2018年9月11日 下午7:13:52 */class MyRequestWrapper extends HttpServletRequestWrapper { private final String body; public String getBody() {return body;} public MyRequestWrapper(final HttpServletRequest request) throws IOException {super(request);StringBuilder sb = new StringBuilder();String line;BufferedReader reader = request.getReader();while ((line = reader.readLine()) != null) { sb.append(line);} body = sb.toString(); } @Override public ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(body.getBytes());return new ServletInputStream() { /* * 重寫ServletInputStream的父類InputStream的方法 */ @Override public int read() throws IOException {return bais.read(); } @Overridepublic boolean isFinished() {return false;} @Overridepublic boolean isReady() {return false;} @Overridepublic void setReadListener(ReadListener listener) {}}; } @Override public BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(this.getInputStream())); }}第二步:在項(xiàng)目的啟動(dòng)類上添加@ServletComponentScan注解,使允許掃描

Servlet組件(過濾器、監(jiān)聽器等)。

SpringBoot使用Filter實(shí)現(xiàn)簽名認(rèn)證鑒權(quán)的示例代碼

測(cè)試一下

測(cè)試說明

客戶端ip在我們?cè)O(shè)置的ip白名單里面 且 timestamp + secret + bodyStringMD5加密后的字段與請(qǐng)求頭域中傳過來的signature值相同時(shí),才算鑒權(quán)通過。

說明:

1.ip白名單 本示例中是設(shè)置在服務(wù)端的相應(yīng)服務(wù)的系統(tǒng)配置文件application.properties中的。2.secret 是客戶端一方和服務(wù)端一方 定好的一個(gè)用來MD5加密的 數(shù),secret本身不進(jìn)行傳輸。3.bodyString是服務(wù)端通過客戶端的request獲取到的請(qǐng)求體中的數(shù)據(jù)。4.signature是客戶端加密后的值,服務(wù)端只需對(duì)原始數(shù)據(jù)進(jìn)行和客戶端進(jìn)一模一樣的加密, 將加密結(jié)果和傳導(dǎo)服務(wù)端的signature進(jìn)行比對(duì),一樣則鑒權(quán)通過。

啟動(dòng)項(xiàng)目,使用postman測(cè)試一下

SpringBoot使用Filter實(shí)現(xiàn)簽名認(rèn)證鑒權(quán)的示例代碼

給出程序打印的日志,更容易理解

SpringBoot使用Filter實(shí)現(xiàn)簽名認(rèn)證鑒權(quán)的示例代碼

提示:由于本人測(cè)試時(shí),我的電腦既是服務(wù)器又是客戶端,所以獲取到了那樣的ip。

注:當(dāng)ip或Authorization值中任意一個(gè)或兩個(gè) 不滿足條件時(shí),會(huì)返回給前端403(見:SignAutheFilter中的相關(guān)代碼), 這里就不給出效果圖了。

由測(cè)試結(jié)果可知:簽名鑒權(quán)成功!

測(cè)試項(xiàng)目代碼托管鏈接: https://github.com/JustryDeng/PublicRepository ​

到此這篇關(guān)于SpringBoot使用Filter實(shí)現(xiàn)簽名認(rèn)證鑒權(quán)的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot Filter簽名認(rèn)證鑒權(quán)內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
国产精品福利电影一区二区三区四区| 日韩亚洲在线| 亚洲欧美视频| 亚洲欧洲综合另类在线| 91丨porny丨在线| 久久久亚洲午夜电影| 不卡的看片网站| 久久久美女艺术照精彩视频福利播放 | 久久一区二区三区四区| 不卡的av中国片| 久久综合久久鬼色| 欧美激情精品久久久六区热门| 中文字幕欧美日韩一区| 黄色国产精品| 一区二区三区免费看视频| 99在线精品视频在线观看| 亚洲精选在线视频| 性欧美长视频| 日本免费新一区视频| 欧美三级电影在线看| 国产综合久久久久久鬼色| 欧美一区二区视频网站| thepron国产精品| 国产欧美久久久精品影院| 一区二区亚洲| 亚洲午夜精品网| 在线观看免费亚洲| 国产精品一区久久久久| 亚洲精品在线电影| 欧美区日韩区| 一区二区三区四区中文字幕| 色又黄又爽网站www久久| 久久国产尿小便嘘嘘尿| 欧美顶级少妇做爰| 成人免费视频一区| 久久精品视频免费观看| 亚洲香蕉视频| 日韩av高清在线观看| 在线不卡欧美精品一区二区三区| eeuss鲁片一区二区三区在线观看| 中文字幕巨乱亚洲| 国产精品久久波多野结衣| 男人的j进女人的j一区| 欧美一区二区女人| 午夜久久资源| 亚洲综合小说图片| 欧美久久久久中文字幕| 97se狠狠狠综合亚洲狠狠| 中文字幕一区在线观看| 久久国产精品亚洲va麻豆| 国产一区二区三区在线看麻豆| 亚洲精品一区二区三区在线观看| 激情另类综合| 日本午夜精品视频在线观看| 日韩三级av在线播放| 一区精品久久| 麻豆成人91精品二区三区| 精品国偷自产国产一区| 亚洲欧洲精品一区| 久草中文综合在线| 国产女人18毛片水真多成人如厕| 国产九区一区在线| 国产精品一二二区| 中文字幕精品在线不卡| 可以看av的网站久久看| 不卡的av电影| 亚洲国产一区二区三区青草影视 | 亚洲柠檬福利资源导航| 欧美午夜精品一区| 欧美国产专区| 免费人成在线不卡| 国产精品日韩精品欧美在线| 色婷婷久久久久swag精品| 9人人澡人人爽人人精品| 亚洲线精品一区二区三区八戒| 欧美一区二区三区免费观看视频 | 97久久久精品综合88久久| 亚洲欧美成人一区二区三区| 精品视频999| 狠狠久久综合婷婷不卡| 久久草av在线| 中文字幕一区二区不卡 | 樱花影视一区二区| 日韩一区二区三区精品视频| av成人国产| 国产成人午夜高潮毛片| 亚洲欧美二区三区| 日韩视频免费观看高清完整版在线观看 | 国产精品日韩欧美一区| 成人午夜电影小说| 偷拍与自拍一区| 国产欧美一区二区精品秋霞影院 | 亚洲一区中文日韩| 欧美电视剧免费观看| 亚洲精品在线视频观看| 国产高清精品久久久久| 一级中文字幕一区二区| 日韩一区二区影院| 久久国产精品毛片| 欧美成人69| 国产精品一区免费在线观看| 亚洲最大色网站| 国产午夜精品在线观看| 欧美日韩成人激情| 亚洲永久网站| 国产在线视频欧美一区二区三区| 国产一区二区成人久久免费影院| 亚洲无线码一区二区三区| 欧美国产精品一区| 欧美美女bb生活片| 亚洲欧美日韩精品一区二区 | 欧美日韩国产一区二区三区地区| 欧美三级视频| 国产99一区视频免费| 日本伊人午夜精品| 亚洲免费av观看| 国产日韩欧美高清| 欧美一区二区福利在线| 91福利在线免费观看| 99re6热在线精品视频播放速度| 91在线观看下载| 国产精品羞羞答答xxdd | 在线观看亚洲| 91原创在线视频| 国产乱码精品1区2区3区| 婷婷综合另类小说色区| 亚洲欧美日韩电影| 久久久亚洲精品石原莉奈| 欧美日韩日日骚| 久久精品国产综合精品| 亚洲黄色天堂| 欧美午夜在线| 99热99精品| 国产91富婆露脸刺激对白| 麻豆国产欧美一区二区三区| 亚洲成国产人片在线观看| 中文字幕日韩av资源站| 国产人妖乱国产精品人妖| 日韩久久久精品| 在线播放中文字幕一区| 色8久久人人97超碰香蕉987| 国产精品毛片va一区二区三区| 亚洲性色视频| 欧美三级在线| 欧美成人综合| 91网站在线播放| 不卡的电视剧免费网站有什么| 国产精品一区一区三区| 国产一区美女在线| 久久国产精品99精品国产| 日韩精品1区2区3区| 亚洲在线免费播放| 亚洲乱码精品一二三四区日韩在线 | 欧美日韩在线精品一区二区三区| 99久久国产免费看| 成人性视频网站| 成人一区在线看| 国产一区二区成人久久免费影院 | 欧美日韩你懂的| 在线欧美一区二区| 久久亚洲风情| 亚洲欧美日韩精品久久久| 亚洲少妇在线| 国产伦精品一区二区三区四区免费 | 亚洲视频日本| 韩日精品视频| 欧美午夜不卡| 一区二区在线视频观看| 在线精品一区| 亚洲视频www| 国产精品综合色区在线观看| 久久国产精品久久精品国产| 久久成人资源| 欧美伊人久久大香线蕉综合69 | 久久经典综合| 欧洲视频一区二区| 91传媒视频在线播放| 色天天综合久久久久综合片| 麻豆成人在线| 欧美在线一区二区| 欧美一区二区在线播放| 欧美大片免费久久精品三p| 日韩欧美的一区| 久久你懂得1024| 国产日韩欧美精品在线| 国产精品电影院| 一区二区三区欧美在线观看| 亚洲国产精品久久久久秋霞影院| 日韩专区一卡二卡| 极品尤物av久久免费看| 成人免费看视频| 欧美精品99| 999亚洲国产精| 久久婷婷国产综合尤物精品| 欧美日韩在线播放一区| 日韩欧美国产高清| 国产精品色哟哟| 亚洲综合999| 久久99精品久久久久久动态图 | 久久亚洲综合网|