让Spring Security更安全的配置办法

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相关文档.

 

或许只是一小点点的改变, 不过将更好.

oauth2-shiro中将authz与resources模块合并到一个项目中如何配置

oauth2-shiro的设计是分模块, 将authz与resources分成不同的子项目来实现. 但现实中有时需要将其合成一个项目, 对于此类场景中,该如何配置security, 具体如下:

1. 在security配置中使用OAuth2CredentialsMatcher类替换authz模块中的HashedCredentialsMatcher与resources模块中的SimpleCredentialsMatcher配置; 具体的配置可参考OAuth2CredentialsMatcher.java类的中注释.

2.在配置ShiroFilterFactoryBean中的filterChainDefinitions的value中添加

/oauth/** = anon

(另外注意合并时的url pattern不要有重复)

配置示例图
OAuth2CredentialsMatcher

注意截图中的OAuth2JdbcRealm只用于resources模块, 在合并后不能使用, 使用其父类MkkJdbcRealm.
http://git.oschina.net/mkk/oauth2-shiro