SpringBoot 는 Filter 를 사용 하여 서명 인증 인증 권한 을 실현 하 는 예시 코드
감 권,많은 방안 이 있 습 니 다.예 를 들 어 SpringSecurity,Shiro,차단기,필터 등 이 있 습 니 다.일부 URL 에 대한 인증 인증 인증 만 한다 면 저 희 는 끝 냅 니 다.
SpringSecurity 나 Shiro 등 프레임 워 크 를 도입 할 필요 가 없고 차단기 나 필 터 를 사용 하면 수 요 를 충족 시 킬 수 있다.
본 고 는 필터 필 터 를 사용 하여 URL 서명 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증
본인 테스트 소프트 하드웨어 환경:Windows 10,Eclipse,SpringBoot,JDK 1.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
# secret
secret = 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()
// = 15
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
} catch (Exception e) {
ipAddress="";
}
return ipAddress;
}
}
STEP 4: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);
}
}
다섯 번 째 단계:컨트롤 러 를 간단하게 작성 하여 뒤의 테스트 를 편리 하 게 합 니 다.SpringBoot 필터 로 서명 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 논리 코드
첫 번 째 단계:필터 작성
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;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public 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(",");
// ip
String 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");
}
}
@Override
public 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();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
두 번 째 단계:프로젝트 의 시작 클래스 에@ServletComponentscan 주 해 를 추가 하여 스 캔 을 허용 합 니 다.Servlet 구성 요소(필터,모니터 등).
테스트 해 봐.
테스트 설명
클 라 이언 트 ip 는 우리 가 설정 한 ip 화이트 리스트 에 있 습 니 다. 타임 스탬프 + secret + body StringMD 5 암호 화 된 필드 는 요청 헤드 필드 에서 전 달 된 signature 값 과 동시에 감 권 이 통 과 됩 니 다.
설명:
1.ip 화이트 리스트 본 예제 에 서 는 서버 의 해당 서비스 에 설 치 된 시스템 프로필 application.properties 에 설 치 된 것 입 니 다.
2.secret 는 클 라 이언 트 측 과 서버 측 이 정 한 MD5 암호 화 에 사용 되 는 것 입 니 다. 수,시 크 릿 자 체 는 전송 하지 않 습 니 다.
3.bodyString 은 서버 에서 클 라 이언 트 의 request 를 통 해 얻 은 요청 체 의 데이터 입 니 다.
4.signature 는 클 라 이언 트 가 암호 화 된 값 입 니 다.서버 는 원본 데 이 터 를 클 라 이언 트 와 똑 같이 암호 화하 기만 하면 됩 니 다.
암호 화 결 과 를 서버 의 signature 와 비교 하면 인증 권 이 통 과 됩 니 다.
프로젝트 시작,post man 으로 테스트 해 보기
프로그램 인쇄 로 그 를 보 내 면 이해 하기 쉽 습 니 다.
알림:본인 이 테스트 할 때 제 컴퓨터 는 서버 이자 클 라 이언 트 이기 때문에 그런 ip 을 얻 었 습 니 다.
주:ip 또는 Authorization 값 중 하나 또는 두 개가 조건 을 만족 시 키 지 못 할 경우 전단 403(SignAuthoseFilter 의 관련 코드 참조)으로 되 돌아 갑 니 다.
여 기 는 효과 도 를 제시 하지 않 겠 습 니 다.
테스트 결과 에서 알 수 있 듯 이 서명 감 권 성공!
테스트 항목 코드 위탁 관리 링크: https://github.com/JustryDeng/PublicRepository
SpringBoot 가 Filter 를 사용 하여 서명 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증 인증
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java・SpringBoot・Thymeleaf】 에러 메세지를 구현(SpringBoot 어플리케이션 실천편 3)로그인하여 사용자 목록을 표시하는 응용 프로그램을 만들고, Spring에서의 개발에 대해 공부하겠습니다 🌟 마지막 데이터 바인딩에 계속 바인딩 실패 시 오류 메시지를 구현합니다. 마지막 기사🌟 src/main/res...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.