目录
背景
基于 Element+SpringCloud 开发的业务系统,并且自签了https证书,一直以为这么做很安全了,突然接到渗透测试通知说有明文传输的问题,吓了一跳,https了还能明文,还有什么应用层抓包,理解不能!!!各种反抗之后无用,改吧,ε=(´ο`*)))唉
先贴结果
整改前
整改后
实现逻辑
理解的并不全面,仅供参考,如有更好的优化方式,请各位大佬指正
根据各种资料,OAuth2 的验证顺序是校验客户端信息(client_id,client_secret)-> 校验用户名密码,需要将这两步认证逻辑重写,将参数解密后再进行认证
1.自定义拦截器,将client解密,并组装Authentication
OAuth2 对client_id和secret拦截是通过ClientCredentialsTokenEndpointFilter实现,核心代码
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (this.allowOnlyPost && !"POST".equalsIgnoreCase(request.getMethod())) {
throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[]{
"POST"});
} else {
String clientId = request.getParameter("client_id");
String clientSecret = request.getParameter("client_secret");
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
return authentication;
} else if (clientId == null) {
throw new BadCredentialsException("No client credentials presented");
} else {
if (clientSecret == null) {
clientSecret = "";
}
clientId = clientId.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId, clientSecret);
return this.getAuthenticationManager().authenticate(authRequest);
}
}
}
接收参数后,判断是否存在client_id参数,如果存在就将client_id和secret 组装AuthenticationToken进行认证,OAuth2 会根据 Token类去获取认证实现类,因为要对secret解密,所以需要对这段代码进行复写
CustomClientCredentialsTokenEndpointFilter
public class CustomClientCredentialsTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
private boolean allowOnlyPost;
public CustomClientCredentialsTokenEndpointFilter(AuthenticationManager authenticationManager) {
super();
this.setAuthenticationManager(authenticationManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (this.allowOnlyPost && !"POST".equalsIgnoreCase(request.getMethod())) {
throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[]{
"POST"});
} else {
String clientId = request.getParameter("client_id");
String clientSecret = request.getParameter("client_secret");
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
return authentication;
} else if (clientId == null) {
throw new BadCredentialsException("No client credentials presented");
} else {
if (clientSecret == null) {
clientSecret = "";
}
clientId = clientId.trim();
ClientAuthenticationToken authRequest = new ClientAuthenticationToken(clientId, clientSecret);
Map<String,String> details = new HashMap<>();
details.put("key",request.