我有一个使用Spring Boot实现的应用程序,在这里我使用Spring Security进行身份验证。我已经有“基于令牌”的身份验证,需要客户端检索令牌,然后使用该令牌在后续请求中进行身份验证。
我想对此进行增强,以便可以将令牌限制为特定的主机名,因此该令牌只能用于来自该主机的请求。这类似于google maps API对其API密钥所做的操作,可以通过IP或主机名限制它们。
这里是我为检索请求的主机名而实现的代码
public String getClientHostName(HttpServletRequest request) {
String hostName = null;
// get the request's IP address
String clientAddress = httpRequest.getRemoteAddr();
String xfHeader = httpRequest.getHeader("X-Forwarded-For");
if (xfHeader != null) {
clientAddress = xfHeader.split(",")[0];
}
// try to resolve the host name from the IP address
try {
InetAddress address = InetAddress.getByName(clientAddress);
hostName = address.getHostName();
} catch (UnknownHostException e) {
logger.error("Failed to get the host name from the request's remote address. ", e);
}
return hostName;
}
我现在有2个问题:
此代码并不总是设法检索主机名。有时它只是返回IP地址。我知道这可能归结为IP spoofing check the InetAddress class does。
当测试来自不同主机的请求时,我并不总是获得期望的IP地址。我经常获得转发请求的另一台主机的IP(我认为可以通过检查“ X-Forwarded-For”来解决)。这使我想知道如何甚至检索作为请求真正发起者的主机的IP。
是否有可靠的方法来检查请求发起者的主机名?
您是否尝试过通过String referrer = request.getHeader("referer");
获取主机名?
此外,在客户端,您还可以添加一个片段以在标题中查找主机名。
或者您可以提供以下要添加到客户端和服务器上的代码,您可以读取将返回主机名的domain的值
<input type="button" value="Register" onClick="call()"/>
<script>
function call(){
var domain=window.location.hostname;
window.open('http://<your-hostname>/register?domain='+domain,'_self');
}
</script>