日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

SpringBoot使用Filter實現簽名認證鑒權的示例代碼

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

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

本人測試軟硬件環境:Windows10、Eclipse、SpringBoot、JDK1.8

準備工作 第一步:在pom.xml中引入相關依賴

<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>第二步:在系統配置文件application.properties中配置相關參數,一會兒代碼中需要用到

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

import java.net.InetAddress;import java.net.UnknownHostException; import javax.servlet.http.HttpServletRequest; /** * 獲取發出request請求的客戶端ip * 注:如果是自己發出的請求,那么獲取的是自己的ip * 摘錄自https://blog.csdn.net/byy8023/article/details/80499038 * * 注意事項: * 如果使用此工具,獲取到的不是客戶端的ip地址;而是虛擬機的ip地址(d當客戶端安裝有VMware時,可能出現此情況); * 那么需要在客戶端的[控制面板網絡和 Internet網絡連接]中禁用虛擬機網絡適配器 * * @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')) { // 根據網卡取本機配置的IP InetAddress inet = null; try {inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) {e.printStackTrace(); } ipAddress = inet.getHostAddress();} } // 對于通過多個代理的情況,第一個IP為客戶端真實IP,多個IP按照’,’分割 if (ipAddress != null && ipAddress.length() > 15) { // '***.***.***.***'.length() // = 15if (ipAddress.indexOf(',') > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(','));} }} catch (Exception e) { ipAddress='';}return ipAddress; }}第四步:準備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);}}第五步:簡單編寫一個Controller,方便后面的測試

SpringBoot使用Filter實現簽名認證鑒權的示例代碼

SpringBoot使用Filter實現簽名認證鑒權 --- 邏輯代碼第一步:編寫過濾器

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使用攔截器實現簽名認證(鑒權) * @WebFilter注解指定要被過濾的URL * 一個URL會被多個過濾器過濾時,還可以使用@Order(x)來指定過濾request的先后順序,x數字越小越先過濾 * * @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);/* * 讀取請求體中的數據(字符串形式) * 注:由于同一個流不能讀取多次;如果在這里讀取了請求體中的數據,那么@RequestBody中就不能讀取到了 * 會拋出異常并提示getReader() has already been called for this request * 解決辦法:先將讀取出來的流數據存起來作為一個常量屬性.然后每次讀的時候,都需要先將這個屬性值寫入,再讀出. *即每次獲取的其實是不同的流,但是獲取到的數據都是一樣的. *這里我們借助HttpServletRequestWrapper類來實現 * 注:此方法涉及到流的讀寫、耗性能; */MyRequestWrapper mrw = new MyRequestWrapper(request);String bodyString = mrw.getBody();logger.info('getted requestbody data is ---> ' + bodyString);// 獲取幾個相關的字符// 由于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內容是否正確,進而判斷是否最終放行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() { } } /** * 輔助類 ---> 變相使得可以多次通過(不同)流讀取相同數據 * * @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())); }}第二步:在項目的啟動類上添加@ServletComponentScan注解,使允許掃描

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

SpringBoot使用Filter實現簽名認證鑒權的示例代碼

測試一下

測試說明

客戶端ip在我們設置的ip白名單里面 且 timestamp + secret + bodyStringMD5加密后的字段與請求頭域中傳過來的signature值相同時,才算鑒權通過。

說明:

1.ip白名單 本示例中是設置在服務端的相應服務的系統配置文件application.properties中的。2.secret 是客戶端一方和服務端一方 定好的一個用來MD5加密的 數,secret本身不進行傳輸。3.bodyString是服務端通過客戶端的request獲取到的請求體中的數據。4.signature是客戶端加密后的值,服務端只需對原始數據進行和客戶端進一模一樣的加密, 將加密結果和傳導服務端的signature進行比對,一樣則鑒權通過。

啟動項目,使用postman測試一下

SpringBoot使用Filter實現簽名認證鑒權的示例代碼

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

SpringBoot使用Filter實現簽名認證鑒權的示例代碼

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

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

由測試結果可知:簽名鑒權成功!

測試項目代碼托管鏈接: https://github.com/JustryDeng/PublicRepository ​

到此這篇關于SpringBoot使用Filter實現簽名認證鑒權的示例代碼的文章就介紹到這了,更多相關SpringBoot Filter簽名認證鑒權內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
樱桃视频成人在线观看| 亚洲精品黄色| 四虎成人精品一区二区免费网站| 久久久蜜桃一区二区人| 国产精品麻豆久久| 人在线成免费视频| 伊人久久高清| 亚洲不卡系列| 在线亚洲成人| 亚洲精品第一| 欧美一级久久| 国产精品对白| 久久久久久色 | 日韩欧美二区| 午夜精品免费| 日韩精品免费一区二区夜夜嗨| 美女国产一区| 欧美亚洲人成在线| 成人三级高清视频在线看| 欧美日韩视频免费观看| 性色av一区二区怡红| 日韩av黄色在线| 激情不卡一区二区三区视频在线| 91精品国产调教在线观看| 久久精品亚洲人成影院| 亚洲精品在线a| 激情综合五月| 亚洲伊人精品酒店| 久久亚洲人体| 日韩在线一区二区| 久草精品视频| 中文字幕亚洲精品乱码| 精品国产亚洲日本| 日本欧美在线看| 久久久久久久欧美精品| 日韩中出av| 999久久久91| 97成人超碰| 99久久99久久精品国产片果冰| 欧美二三四区| 综合五月婷婷| 欧美va天堂在线| 国产精品男女| 亚洲欧美日韩综合国产aⅴ| 久久成人福利| 欧美一区免费| 美女日韩在线中文字幕| 久久毛片亚洲| 久久国际精品| 中文视频一区| 五月激情久久| 久久影院午夜精品| 里番精品3d一二三区| 亚洲免费毛片| 欧美手机在线| 亚洲最新无码中文字幕久久 | 国产伦理一区| 欧美亚洲国产日韩| 无码日韩精品一区二区免费| 国产精品av一区二区| 国产精品久久久久蜜臀| 国产精品qvod| 日本在线不卡视频一二三区| 久久亚洲美女| 日韩一区精品字幕| 蜜桃久久精品一区二区| 日韩亚洲一区在线| 美腿丝袜亚洲一区| 麻豆国产精品| 福利视频一区| 亚洲a一区二区三区| 亚洲午夜黄色| 在线视频日韩| 日本成人一区二区| 亚洲久久视频| 国产欧美日韩视频在线| 国产精品色在线网站| 国产乱码精品一区二区亚洲| 麻豆视频久久| 久久久久免费av| 男女男精品视频网| 国产精品毛片久久久| 国产精品精品国产一区二区| 天堂日韩电影| 伊人影院久久| 日本免费在线视频不卡一不卡二| 国产三级精品三级在线观看国产| 国产精品高清一区二区| 综合日韩av| 亚洲日本在线观看视频| 成人国产精品久久| 日韩中文字幕区一区有砖一区| 国产视频一区二区在线播放| 国产成人久久精品一区二区三区| 日韩成人高清| 亚洲无线观看| 国产伦久视频在线观看| 亚洲免费精品| 国产不卡精品在线| 亚洲综合图色| 九九精品调教| 欧美在线91| 爽好多水快深点欧美视频| 美女性感视频久久| 亚洲专区欧美专区| 国产videos久久| 日韩精品亚洲专区| 蜜桃成人精品| **爰片久久毛片| 自拍日韩欧美| 亚洲人成在线网站| 国产精品久久免费视频| 亚洲中午字幕| 欧美色图国产精品| 国产一区二区三区探花| 日韩激情综合| 午夜精品影视国产一区在线麻豆| 五月天久久久| 91精品国产福利在线观看麻豆| 精品欧美视频| 日韩激情视频网站| 视频一区二区三区入口| 特黄毛片在线观看| 欧美日韩中文| 日韩精品91亚洲二区在线观看| 一本色道久久精品| 日韩视频一区| 六月婷婷一区| 美国欧美日韩国产在线播放| 国产亚洲综合精品| 国产精品普通话对白| 亚洲一区二区三区高清不卡| 欧美日韩国产亚洲一区| 亚洲精品网址| 亚洲欧美成人综合| 免费在线看一区| 欧美亚洲人成在线| 激情久久99| 欧美黄页在线免费观看 | 视频在线观看91| 97久久中文字幕| 国产日产一区| 国产videos久久| 欧洲精品一区二区三区| 久久久国产精品一区二区中文| 久久久久国产精品一区三寸| 91精品1区| 青青草精品视频| 精品国产乱码久久久| 日韩国产一区二区三区| 久久精品亚洲| 日韩在线观看一区| 久久国产66| 日韩一区精品| 人人草在线视频| 99成人在线| 久久久国产精品入口麻豆| 免费福利视频一区二区三区| 国产精品免费看| 九九久久国产| 欧美中文字幕| 精品三级在线观看视频| 亚洲在线成人| 日韩欧美视频专区| 日韩av字幕| 日韩黄色大片网站| 色狠狠一区二区三区| 日韩电影免费网址| 日本一不卡视频| 亚洲午夜视频| 97精品中文字幕| 免播放器亚洲一区| 六月婷婷综合| 久久精品国产99国产| 亚洲精品在线国产| 亚洲二区免费| 天堂中文在线播放| 国产日韩一区二区三免费高清 | 日本欧美不卡| 欧美一级二区| 99视频精品| 蜜臀久久精品| 国产麻豆一区二区三区| 国产一级久久| 色爱av综合网| 国内精品伊人| 日韩av中文在线观看| 国产精品美女| av不卡在线| 中文欧美日韩| 午夜国产精品视频免费体验区| 日本精品在线中文字幕| 国产麻豆一区二区三区| 日韩精品一区二区三区av| 视频一区二区三区中文字幕| 91久久中文| 久久亚洲风情| 亚洲精品高潮| 国产日韩欧美在线播放不卡| 日韩毛片一区|