今天尝试看了下 spring security中 cookie的使用 。 实现了自定的cookie ,在cookie中加入了 ip的绑定 。废话多说,直接上代码
重写了 TokenBasedRememberMeServices 类。实现了自定义的 RememberMeServices
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.codec.Hex;
import org.springframework.security.web.authentication.rememberme.InvalidCookieException;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
public class IpTokenBasedRememberMeSerivces extends TokenBasedRememberMeServices {
private static final ThreadLocal<HttpServletRequest> requestHolder =
new ThreadLocal<HttpServletRequest>();
public HttpServletRequest getContext()
{
return requestHolder.get();
}
public void setContext(HttpServletRequest context)
{
requestHolder.set(context);
}
//工具类,获取 ip
protected String getUserIPAddress(HttpServletRequest request)
{
return request.getRemoteAddr();
}
@Override
public void onLoginSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication successfulAuthentication) {
// TODO Auto-generated method stub
setContext(request);
super.onLoginSuccess(request, response, successfulAuthentication);
setContext(null);
}
//将ip地址加入搭配cookie中
@Override
protected void setCookie(String[] tokens, int maxAge,
HttpServletRequest request, HttpServletResponse response) {
String[] tokensWidthIpAddress = Arrays.copyOf(tokens, tokens.length+1);
tokensWidthIpAddress[tokensWidthIpAddress.length-1] =getUserIPAddress(request);
super.setCookie(tokens, maxAge, request, response);
}
//将ip加入转换成 md5的字符串中
@Override
protected String makeTokenSignature(long tokenExpiryTime, String username, String password) {
//加入将ip信息 加入cookie中
String data = username + ":" + tokenExpiryTime + ":" + password + ":" + getKey()+
":"+getUserIPAddress(getContext()).getBytes();
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("No MD5 algorithm available!");
}
return new String(Hex.encode(digest.digest(data.getBytes())));
}
//重写处理 自动登陆的代码
@Override
protected UserDetails processAutoLoginCookie(String[] cookieTokens,
HttpServletRequest request, HttpServletResponse response) {
String ipAddressToken = cookieTokens[cookieTokens.length-1];
if(!getUserIPAddress(request).equals(ipAddressToken))
{
throw new InvalidCookieException("IP 不匹配");
}
return super.processAutoLoginCookie(cookieTokens, request, response);
}
}
配置 beans.xml:
<bean class="com.packtpub.springsecurity.security.IPTokenBasedRememberMeServices" id="ipTokenBasedRememberMeServicesBean">
<property name="key"><value>remberMe</value></property>
<property name="userDetailsService" ref="userService"/>
</bean>
在 security.xml 中:
<http>
<!-- remberme 功能 -->
<remember-me key="remberMe" services-ref="ipTokenBasedRememberMeServicesBean"/>
</http>
<user-service id="userService">
重启服务器 。
因为remember me cookie是Base64编码的,我们能够使用一个Base64解码的工具得到cookie的值以证实我们的新增功能是否生效。如果我们这样做的话,我们能够看到一个名为SPRING_SECURITY_REMEMBER_ME_COOKIE的cookie的内容大致如下所示:
admin:1251695034322:776f8ad44034f77d13218a5c431b7b34:127.0.0.1
admin:是用户名.
1251695034322:cookie到期的时间
76f8ad44034f77d13218a5c431b7b34:是 用户名 ,密码 ,和绑定ip的MD5值
127.0.0.1是我们绑定的ip