package com.yifu.cloud.plus.v1.yifu.auth.filter;

import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author fxj *
 * @date 2022年05月27日 11:14
 * @description
 */
@Log4j2
@Data
@Order(-1)
@RequiredArgsConstructor
public class PasswordDecoderFilter extends UsernamePasswordAuthenticationFilter {

	private static final String KEY_ALGORITHM = "AES";
	/**
	 * 解密登录前端密码 秘钥
	 */
	private String encodeKey = "thanks,pig4cloud";

	private boolean postOnly = true;

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		if (this.postOnly && !request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		} else {
			String username = this.obtainUsername(request);
			username = username != null ? username : "";
			username = username.trim();
			String password = this.obtainPassword(request);
			password = password != null ? decryptAES(password) : "";

			UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
			this.setDetails(request, authRequest);
			return this.getAuthenticationManager().authenticate(authRequest);
		}
	}
	/**
	 * 原文解密
	 * @return
	 */
	private String decryptAES(String password) {
		// 构建前端对应解密AES 因子
		AES aes = new AES(Mode.CFB, Padding.NoPadding,
				new SecretKeySpec(encodeKey.getBytes(), KEY_ALGORITHM),
				new IvParameterSpec(encodeKey.getBytes()));
		// 解密
		return  aes.decryptStr(password);
	}
}
