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

 

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

解决Spring Security 表单上传文件CSRF失效的问题

在Spring Security4中引入的CSRF是不错的安全机制. 但在常用的上传文件中(form提交, post, 使用commons-fileupload)会导致CSRF失效,

这问题的根源在于CSRF无法获取表单中的_csrf 的值引起的(可在CsrfFilter打断点查看).

之前我也被这问题困惑了一天, 不知如何是好.

解决之道如下:

1.升级项目中使用的Servlet API版本至3.0及以上.

2.不要使用commons-fileupload组件,即CommonsMultipartResolver , 而使用Servelt提供的组件对象StandardServletMultipartResolver

其在Spring MVC中的配置如下:

<bean id=”multipartResolver”
class=”org.springframework.web.multipart.support.StandardServletMultipartResolver”>
</bean>

3.在Spring MVC的DispatchServlet配置中添加如下配置(web.xml中)

<multipart-config>
<!–location>/tmp</location–>
<max-file-size>1000000</max-file-size>
</multipart-config>

其中的<max-file-size>即限制上传文件的大小. 完整的DispatchServelt配置如下:

<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
<multipart-config>
<!–location>/tmp</location–>
<max-file-size>1000000</max-file-size>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

 

注意在升级Servlet API后需要将web.xml的状况声明也更新为3.0的,如下:

<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd”
version=”3.0″>

 

至此, CSRF工作正常.

分析大概的原因是commons-fileupload组件对request进行封装时对CSRF的支持有问题. 没将_csrf值传递.

参考文章: http://stackoverflow.com/questions/25185578/spring-security-3-2-csrf-and-multipart-requests

 

spring-oauth-server 0.4-beta 发布, Oauth2 与 Spring Security 安全应用整合

spring-oauth-server 0.4-beta版本发布, spring-oauth-server 是一个整合Oauth2与Spring Security的安全应用项目,是从https://github.com/spring-projects/spring-security-oauth/tree/master/spring-security-oauth2扩展的符合实际项目需要的开源项目.

 

0.4-beta版本有重大的更新, 主要在更新了依赖的各类版本, 更新的内容如下:

  • (109) – 升级 spring-security-oauth2 的版本到2.0.7.RELEASE, 旧版本为1.0.5
  • (113) – Upgrade spring, spring security version to > 4.0; 具体版本为Spring: 4.1.6.RELEASE, Spring Security: 4.0.1.RELEASE
  • Upgrade JAVA JDK to 1.8; Servlet 3.0
  • 将项目添加到在线测试服务器, 地址为:https://andaily.com/spring-oauth-server/
  • (115) – Sync update spring-oauth-client version with spring-oauth-server
  • (116) – Remove mybatis dependency, only JDBC
  • Oauth database table add index
  • (97) – Fix custom access_token_validity,refresh_token_validity issue(#5)

 

0.4-beta版本访问地址: http://git.oschina.net/shengzhao/spring-oauth-server/tree/0.4-beta/

 

spring-oauth-server HomePage: http://git.oschina.net/shengzhao/spring-oauth-server

spring-oauth-server 数据扩展实现思路

spring-oauth-server 默认使用数据库MySql实现数据存储, 使用MyBatis, JDBC实现数据库连接与处理.

但在实际项目使用过程中, 有的项目需要使用其他的数据存储解决方案, 如 LDAP, 文件, ACCESS, REDIS, MongoDB等等. 这时如何办, 如何去扩展呢? 在此给一些步骤与建议.具体如下

 

1. 在项目中加入必要的MAVEN dependencies; 如 redis的, LDAP的.(建议使用基于spring-data 系列的, 方便与Spring 整合);  并去掉不需要的dependencies, (如当前的 mybatis, mysql);

2. 用你需要的存储技术 实现spring-security-oauth2提供的以下3个接口:

  • AuthorizationCodeServices
  • TokenStore
  • ClientDetailsService

3.修改security.xml中的对应的3个接口的默认配置, 分别为 JdbcTokenStore, CustomJdbcClientDetailsService, JdbcAuthorizationCodeServices;  用自己实现的替换默认的.

4.测试修改. 保证oauth_test.txt(位于others目录)中的示例能够正常运行, 或使用spring-oauth-client测试

 

扩展

若需要完全替换掉MYSQL, 则还需要提供 OauthRepository 与 UserRepository 的实现并配置.

 

——————————————————————————

若需要提供商业化的技术支持 或 提供整套的技术方案, 请联系 sz@monkeyk.com

 

http://git.oschina.net/shengzhao/spring-oauth-server

启用/禁用各类grant_type (spring-oauth-server)

默认在spring-oauth-server项目中启用了OAUTH支持的五类grant_type(http://andaily.com/blog/?p=103),

但如果根据实际需求只需要启用或禁用某一类或某几类grant_type,其配置如下图:

disable_grant_type

在security.xml文件中修改配置即可启用/禁用某一类grant_type, 对应的添加 disabled=”true” 属性即可禁用某一类grant_type.

 

http://git.oschina.net/shengzhao/spring-oauth-server

spring-oauth-server 0.3 发布, Oauth2与Spring Security安全应用整合

spring-oauth-server 0.3版本发布, spring-oauth-server 是一个整合Oauth2与Spring Security的安全应用项目,是从https://github.com/spring-projects/spring-security-oauth/tree/master/spring-security-oauth2扩展的符合实际项目需要的示例项目.

0.3版本是项目创建后的第一个重大版本, 更新内容如下:

  • #74 – oauth mysql ddl add create_time, default is now()
  • #75 – Add user information API, for spring-oauth-client project use
  • #77 – User add Privilege domain. Addition initial two user: unityuser(ROLE_UNITY),mobileuser(“ROLE_MOBILE). If default user, return all privilegs, otherwise return specify privilege(s)
  • #78 – Initial ‘sprint-oauth-client’ project(maven), add sub-modules#78 – Initial ‘sprint-oauth-client’ project(maven), add sub-modules
  • #91 – User log4j replace logback dependency
  • #92 – Add database table column description. (添加数据库表的字段说明)
  • #93 – 将默认的 oauth_code存入数据库(当前是存入内存)
  • spring-oauth-server project add Bootstrap CSS
  • #95 – Add ‘client-details’ management; create/delete, show testing links

 

0.3版本访问地址: http://git.oschina.net/shengzhao/spring-oauth-server/tree/0.3/

项目地址: http://git.oschina.net/shengzhao/spring-oauth-server