Spring Security, 不错的安全框架,但在实际项目中, 如何让安全更安全呢? 以下是在实际项目中总结的经验之谈.
(以Spring Secuirty 4.0.1版本为基础)
1.登录时的参数名(username, password)不要使用默认的. 登录,退出的URL不要使用默认的.
Secuiry中默认的用户名参数为username, 密码为password; 在配置中修改不要使用默认的, 如username修改为uid, password为pwd__等等;
同样, 登录的URL与退出时的URL也配置为不使用默认的, 一个配置参考如下
<form-login authentication-failure-url="/login?error=1" default-target-url="/index" always-use-default-target="true" username-parameter="uid" password-parameter="pwd__" login-page="/login_" login-processing-url="/sign_in"/> <logout logout-success-url="/index" logout-url="/sign_out"/>
2.升级Spring Secuirty到4.0或之后的版本, 启用CSRF, 防止跨站请求伪造登录
如果还在使用Secuirty 3或更老的版本, 升级到4.0或之后 的版本, Security将默认启用CSRF, 可防止跨站请求伪造登录, 或是用机器登录
若不需要CSRF的场景(如对外的API接口), 可在Security配置中关闭, 在<http中配置如下
<csrf disabled="true"/>
3.退出时清除维持会话(Session)的cookie 默认情况在退出时Security会调用Session的invalidate()方法, 但不会清除维持会话的cookie,
我们要配置为在退出时清除该cookie — 使用不同的服务器的cookie值可能不同, 以Tomcat使用的默认cookie名为JSESSIONID为例, 其配置如下
<logout logout-success-url="/index" logout-url="/signout" delete-cookies="JSESSIONID"/>
也可扩展一个LogoutSuccessHandler的实现类来完成该功能.
4.进入登录页面时使用新的Session, 销毁旧的Session
也就是在进入登录页面的请求中调用Session的invalidate()方法, 强制服务器使用一个新的session id.示例如下
@RequestMapping(value = "login", method = RequestMethod.GET) public String login(HttpServletRequest request) throws Exception { request.getSession().invalidate(); return "login"; }
5.用户密码的存储除了加密外, 还需要salt 用户密码的安全永远不能忽略, 不仅要使用不可逆的加密算法(如MD5), 还需要配置salt值,且是动态的salt值(一般使用username或用户的其他属性),示例配置如下
<authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="userService"> <password-encoder hash="md5"> <salt-source user-property="username"/> </password-encoder> </authentication-provider> </authentication-manager>
其他一些相关的设置
1.用户名usernmae的输入框添加 autocomplete=’off’ 属性
这是一个在页面上禁止浏览器记住输入框中输入过的用户名的设置, 添加后就永远不记住之前人登录的用户名了,示例如下:
<input type="text" name="uid_" placeholder="输入用户名" required="" autocomplete="off"/>
2.记录登录失败的信息与次数. 在Security中配置AuthenticationFailureHandler类的实现, 记住用户登录失败的信息,或添加如登录失败三次就需要有验证码等功能, 防止暴力破解用户信息.
3.Concurrent Session控制同一账号同时登录的人数.
若需要一个账号同时只能有一个(或具体的数量)在登录,则添加该配置, 具体参考Spring Security相关文档.
或许只是一小点点的改变, 不过将更好.