第 6 章 控制用户信息

转载:http://www.mossle.com/docs/auth/html/ch006-user-info.html

第 6 章 控制用户信息

让我们来研究一些与用户信息相关的功能,包括为用户密码加密,缓存用户信息,获得系统当前登陆的用户,获得登陆用户的所有权限。

6.1. MD5加密

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

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

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

INSERT INTO USERS VALUES(‘admin‘,‘21232f297a57a5a743894a0e4a801fc3‘,TRUE)
INSERT INTO USERS VALUES(‘user‘,‘ee11cbb19052e40b07aac0ca060c23ee‘,TRUE)
        

现在密码部分已经面目全非了,即使有人攻破了数据库,拿到这种“乱码”也无法登陆系统窃取客户的信息。

下一步为了让Spring Security支持MD5加密,我们需要修改一下配置文件。

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

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

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

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

6.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>
        

在password-encoder下添加了salt-source,并且指定使用username作为盐值。

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

我们这里将每个用户的username作为盐值,最后数据库中的密码部分就变成了这样:

INSERT INTO USERS VALUES(‘admin‘,‘ceb4f32325eda6142bd65215f4c0f371‘,TRUE)
INSERT INTO USERS VALUES(‘user‘,‘47a733d60998c719cf3526ae7d106d13‘,TRUE)
        

6.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"

        eternal="false"

        timeToIdleSeconds="600"

        timeToLiveSeconds="3600"

        overflowToDisk="true"

    />
</ehcache>


内存中最多存放100个对象。



不是永久缓存。



最大空闲时间为600秒。



最大活动时间为3600秒。



如果内存对象溢出则保存到磁盘。

如果想了解有关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中对用户缓存的操作全部失效。

6.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模式,我们会在后面详细介绍。这里我们已经了解了如何获得当前登陆用户的信息。


[5所谓字典攻击,就是指将大量常用字符串使用md5加密,形成字典库,然后将一段由md5演算得到的未知字符串,在字典库中进行搜索,当发现匹配的结果时,就可以获得对应的加密前的字符串内容。

时间: 2024-10-14 21:15:14

第 6 章 控制用户信息的相关文章

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

1. MD5加密 任何一个正式的企业应用中,都不会在数据库中使用明文来保存密码的,我们在之前的章节中都是为了方便起见没有对数据库中的用户密码进行加密,这在实际应用中是极为幼稚的做法.可以想象一下,只要有人进入数据库就可以看到所有人的密码,这是一件多么恐怖的事情,为此我们至少要对密码进行加密,这样即使数据库被攻破,也可以保证用户密码的安全. 最常用的方法是使用MD5算法对密码进行摘要加密,这是一种单项加密手段,无法通过加密后的结果反推回原来的密码明文. 首先我们要把数据库中原来保存的密码使用MD5

第2章 系统用户/组管理

2.1 用户和组的基本概念 用户和组是操作系统中一种身份认证资源. 每个用户都有用户名.用户的唯一编号uid(user id).所属组及其默认的shell,可能还有密码.家目录.附属组.注释信息等. 每个组也有自己的名称.组唯一编号gid(group id).一般来说,gid和uid是可以不相同的,但绝大多数都会让它们保持一致,大致属于约定俗成类的概念吧. 组分为主组(primary group)和辅助组(secondary group)两种,用户一定会属于某个主组,也可以同时加入多个辅助组.

第五章,用户的理解

################ ####第五单元#### ################ ################## ####1.用户理解#### ################## 用户就是系统使用者的身份在系统中用户存储为若干窜字符+若干个系统配置文件 用户信息涉及到的系统配置文件: /etc/passwd###用户信息 用户:密码:uid:gid:说明:家目录:用户使用的shell /etc/shadow###用户认证信息 用户:密码:最后一次密码修改该时间:最短有效期:最

SQL Server 2005 控制用户权限访问表

转自:http://www.cnblogs.com/gaizai/archive/2011/07/14/2106617.html 一.需求 在管理数据库过程中,我们经常需要控制某个用户访问数据库的权限,比如只需要给这个用户访问某个表的权限,甚至是CRUD的权限,更小粒度的还可以去到某几个字段的访问权限.写这篇文章就是说明下这个操作过程. 其实这只是SQL Server权限管理很简单的一小块,有些地方并没有深入理解和讲述,只是希望对一些刚入门的童鞋有帮助,其它大侠就当是:我当堂吓一跳,然后得啖笑.

powershell 生成随机用户信息

#生成随机用户信息,包括姓名.QQ.邮箱,手机号 [email protected]('一','丁','三','专','世','业','丝','中','丰','临','丹','丽','举','乃','义', '乐','乔','书','云','亘','亮','人','仁','今','仙','令','仪','伟','伯','伶','佑','作', '佩','佳','侠','侬','俊','俏','俐','信','修','倩','健','偲','儿','允','元','兆','光', '兰','兴',

第2章 系统用户/组管理(2) su和sudo

本文目录: 2.1 su 2.2 sudo 2.2.1 /etc/sudoers文件 2.2.2 sudo和sudoedit命令 2.1 su 切换用户或以指定用户运行命令. 使用su可以指定运行命令的身份(user/group/uid/gid). 为了向后兼容,su默认不会改变当前目录,且仅设置HOME和SHELL这两个环境变量(若目标用户非root,则还设置USER和LOGNAME环境变量).推荐使用--login选项(即"-"选项)避免环境变量混乱. su [options...

UWP 应用获取各类系统、用户信息 (1) - 设备和系统的基本信息、应用包信息、用户数据账户信息和用户账户信息

应用开发中,开发者时常需要获取一些系统.用户信息用于数据统计遥测.问题反馈.用户识别等功能.本文旨在介绍在 Windows UWP 应用中获取一些常用系统.用户信息的方法.示例项目代码可参见 Github: https://github.com/validvoid/UWP-SystemInfoCollector 由于涉及内容较多,故本文会分为多篇展开.本篇介绍获取设备和系统的基本信息.应用包信息.用户数据账户信息和用户账户信息. 原博客阅读地址:http://validvoid.net/uwp-

CAS学习笔记(三)—— SERVER登录后用户信息的返回

一旦CAS SERVER验证成功后,我们就会跳转到客户端中去.跳转到客户端去后,大家想一想,客户端总要获取用户信息吧,不然客户端是怎么知道登录的是哪个用户.那么客户端要怎么获取用户信息呢? 其实验证成功,跳转客户端这个过程中,CAS SERVER 会返回登录的相关信息给客户端,客户端只要进行获取,就能知道登录的具体是哪个用户了.不过CAS 默认只返回用户账号给客户端,那么怎么定义CAS SERVER返回的信息呢? 这就是本篇具体讲解的内容了,大家听我慢慢道来. 相关接口            

第01章 mySQL用户和权限管理v1

韩立刚老师视频教学网站 http://www.91xueit.com 韩老师QQ458717185 第01章 MySQL用户和权限管理 mySQL权限控制通过两步控制,能不能连接(验证用户身份),能执行什么操作(验证用户权限). 验证用户身份,需要验证,连接mySQL的计算机的IP地址或计算机名称,用户账户和密码.验证过程如下: 管理mySQL用户 查看mySQL用户账户 mySQL用户存储在mysql数据库的user表,该表在mySQL服务启动时自动加载到内存,控制用户的登录. [[email