spring security 控制用户信息用户加密 缓存用户信息

1. MD5加密

任何一个正式的企业应用中,都不会在数据库中使用明文来保存密码的,我们在之前的章节中都是为了方便起见没有对数据库中的用户密码进行加密,这在实际应用中是极为幼稚的做法。可以想象一下,只要有人进入数据库就可以看到所有人的密码,这是一件多么恐怖的事情,为此我们至少要对密码进行加密,这样即使数据库被攻破,也可以保证用户密码的安全。

最常用的方法是使用MD5算法对密码进行摘要加密,这是一种单项加密手段,无法通过加密后的结果反推回原来的密码明文。

首先我们要把数据库中原来保存的密码使用MD5进行加密:

<authentication-provider>
    <password-encoder hash="md5"/>
    <jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>

启用MD5算法。用户登录时,输入的密码是明文,需要使用password-encoder将明文转换成md5形式,然后再与数据库中的已加密密码进行比对。

这些配置对普通客户不会造成任何影响,他们只需要输入自己的密码,Spring Security会自动加以演算,将生成的结果与数据库中保存的信息进行比对,以此来判断用户是否可以登陆。

这样,我们只添加了一行配置,就为系统带来了密码加密的功能。

2. 盐值加密

上面的实例在现实使用中还存在着一个不小的问题。虽然md5算法是不可逆的,但是因为它对同一个字符串计算的结果是唯一的,所以一些人可能会使用“字典攻击”的方式来攻破md5加密的系统[5]。这虽然属于暴力解密,却十分有效,因为大多数系统的用户密码都不回很长。

实际上,大多数系统都是用admin作为默认的管理员登陆密码,所以,当我们在数据库中看到“21232f297a57a5a743894a0e4a801fc3”时,就可以意识到admin用户使用的密码了。因此,md5在处理这种常用字符串时,并不怎么奏效。

为了解决这个问题,我们可以使用盐值加密“salt-source”。

修改配置文件:

<authentication-provider>
    <password-encoder hash="md5">
        <salt-source user-property="username"/>
    </password-encoder>
    <jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>

盐值的原理非常简单,就是先把密码和盐值指定的内容合并在一起,再使用md5对合并后的内容进行演算,这样一来,就算密码是一个很常见的字符串,再加上用户名,最后算出来的md5值就没那么容易猜出来了。因为攻击者不知道盐值的值,也很难反算出密码原文。

3. 用户信息缓存

介于系统的用户信息并不会经常改变,因此使用缓存就成为了提升性能的一个非常好的选择。Spring Security内置的缓存实现是基于ehcache的,为了启用缓存功能,我们要在配置文件中添加相关的内容。

<authentication-provider>
    <password-encoder hash="md5">
        <salt-source user-property="username"/>
    </password-encoder>
    <jdbc-user-service data-source-ref="dataSource" cache-ref="userCache"/>
</authentication-provider>

我们在jdbc-user-service部分添加了对userCache的引用,它将使用这个bean作为用户权限缓存的实现。对userCache的配置如下所示:

<beans:bean id="userCache" class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
    <beans:property name="cache" ref="userEhCache"/>
</beans:bean>

<beans:bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
    <beans:property name="cacheManager" ref="cacheManager"/>
    <beans:property name="cacheName" value="userCache"/>
</beans:bean>

<beans:bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>

EhCacheBasedUserCache是Spring Security内置的缓存实现,它将为jdbc-user-service提供缓存功能。它所引用的userEhCache来自spring提供的EhCacheFactoryBean和EhCacheManagerFactoryBean,对于userCache的缓存配置放在ehcache.xml中:

<ehcache>
    <diskStore path="java.io.tmpdir"/>

    <defaultCache
        maxElementsInMemory="1000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
    />

    <cache
        name="userCache"
        maxElementsInMemory="100"//内存中最多存放100个对象
        eternal="false"//不是永久缓存
        timeToIdleSeconds="600"//最大空闲时间是600s
        timeToLiveSeconds="3600"//最大活动时间是3600s
        overflowToDisk="true"//如果内存对象溢出则保存到磁盘
    />
</ehcache>

如果想了解有关ehcache的更多配置,可以访问它的官方网站http://ehcache.sf.net/

这样,我们就为用户权限信息设置好了缓存,当一个用户多次访问应用时,不需要每次去访问数据库了,ehcache会将对应的信息缓存起来,这将极大的提高系统的相应速度,同时也避免数据库符合过高的风险。

注意

cache-ref隐藏着一个陷阱,如果不看代码,我们也许会误认为cache-ref会在JdbcUserDetailsManager中设置对应的userCache,然后只要直接执行JdbcUserDetailsManager中的方法,就可以自动维护用户缓存。

可惜,cache-ref实际上是在JdbcUserDetailsManager的基础上,生成了一个CachingUserService,这个CachedUserDetailsService会拦截loadUserByUsername()方法,实现读取用户信息的缓存功能。我们在cache-ref中引用的UserCache实际上是放在CacheUserDetailsService中,而不是放到了原有的JdbcUserDetailsManager中,这就会导致JdbcUserDetailsManager中对用户缓存的操作全部失效。

4. 获取当前用户信息

如果只是想从页面上显示当前登陆的用户名,可以直接使用Spring Security提供的taglib。

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<div>username : <sec:authentication property="name"/></div>
        

如果想在程序中获得当前登陆用户对应的对象。

UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext()
    .getAuthentication()
    .getPrincipal();
        

如果想获得当前登陆用户所拥有的所有权限。

Collection<GrantedAuthority> authorities = (Collection<GrantedAuthority>) userDetails.getAuthorities();;
        

关于UserDetails是如何放到SecuirtyContext中去的,以及Spring Security所使用的TheadLocal模式,我们会在后面详细介绍。这里我们已经了解了如何获得当前登陆用户的信息。

时间: 2024-10-06 00:07:31

spring security 控制用户信息用户加密 缓存用户信息的相关文章

Spring Security笔记:使用数据库进行用户认证(form login using database)

在前一节,学习了如何自定义登录页,但是用户名.密码仍然是配置在xml中的,这样显然太非主流,本节将学习如何把用户名/密码/角色存储在db中,通过db来实现用户认证 一.项目结构 与前面的示例相比,因为要连接db,所以多出了一个spring-database.xml用来定义数据库连接,此外,为了演示登录用户权限不足的场景,加了一个页面403.jsp,用来统一显示权限不足的提示信息 二.数据库表结构(oracle环境) 1 create table T_USERS 2 ( 3 d_username

Spring Security笔记:使用数据库进行用户认证(form login using database) - 菩提树下的杨过 - 博客园

body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI",Tahoma,Helvetica,Sans-Serif,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5;

Spring Security控制权限

Spring Security控制权限 1,配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我们就可以控制对这个项目的每个请求了. <filter>    <filter-name>springSecurityFilterChain</filter-name>    <filter-class>org.springframework.web.filter.DelegatingFilterProxy&

spring security控制session

spring security控制session本文给你描述在spring security中如何控制http session.包括session超时.启用并发session以及其他高级安全配置. 创建session时机我们可以准确地控制什么时机创建session,有以下选项进行控制: always – 如果session不存在总是需要创建: ifRequired – 仅当需要时,创建session(默认配置): never – 框架从不创建session,但如果已经存在,会使用该session

Spring MVC、Mybatis、Hibernate、Bootstrap、HTML5、jQuery、Spring Security安全权限、Lucene全文检索、Ehcache分布式缓存 、高性能、高并发【Java企业通用开发平台框架】

功能特点: 1.适配所有设备(PC.平板.手机等),兼容所有浏览器(Chrome.Firefox.Opera.Safari.IE6~IE11等),适用所有项目(MIS管理信息系统.OA办公系统.ERP企业资源规划系统.CRM客户关系管理系统.网站.管理后台等). 2.快速开发,敏捷的数据持久层解决方案. 2.1.事务自动处理. 2.2.O/R Mapping基于注解,零配置XML,便于维护,学习成本低. 2.3.接口和实现分离,不需写数据持久层代码,只需写接口,自动生成添加.修改.删除.排序.分

Spring Security 3 (三) 用户数据存放于数据库

上章回顾: 上一章中,我们将用户名.密码以及用户对应的角色都配置于applicationContext-security.xml中,基本实现了我们能控制用户的访问权限.但是在现实开发中,我们不可能将用户信息硬编码在配置文件中,通常我们都是存放到数据中.同时我们应该对用户的密码进行加密存储. 目标: 1.将用户信息存放于数据库 2.对用户的密码进行加密 详细操作: 1.其他代码参考上一章中代码.本章中,首先我们要创建一张数据表来记录我们的用户信息.SpringSecurity提供的验证机制中,首先

用spring security实现简单的登陆和权限角色控制

 随笔简介 spring版本:4.3.2.RELEASE+spring security 版本:4.1.2.RELEASE(其它不做说明) 所展示内容全部用注解配置 springmvc已经配置好,不作说明 会涉及到springmvc,spel,el的东西,不熟悉的同学可以先去看一下这方面内容,特别是springmvc 首先想一下,登陆需要什么,最简单的情况下,用户名,密码,然后比对数据库,如果吻合就跳转到个人页面,否则回到登陆页面,并且提示用户名密码错误.这个过程中应该还带有权限角色,并且贯穿整

Spring Security OAuth2 开发指南。

官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. Spring OAuth2.0 提供者实现原理: Spring OAuth2.0提供者实际上分为: 授权服务 Authorization Service. 资源服务 Resource Service. 虽然这两个提供者有时候可能存在同一个应用程序中,但在Spring Security OAuth中你可以把 他它们各自放在

Spring Security教程系列(一)基础篇

第 1 章 一个简单的HelloWorld 第 1 章 一个简单的HelloWorld Spring Security中可以使用Acegi-1.x时代的普通配置方式,也可以使用从2.0时代才出现的命名空间配置方式,实际上这两者实现的功能是完全一致的,只是新的命名空间配置方式可以把原来需要几百行的配置压缩成短短的几十行.我们的教程中都会使用命名空间的方式进行配置,凡事务求最简. 1.1. 配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我