将 Shiro 作为应用的权限基础 五:密码的加密/解密在Spring中的应用

考虑系统密码的安全,目前大多数系统都不会把密码以明文的形式存放到数据库中。

一把会采取以下几种方式对密码进行处理

密码的存储

“编码”存储

Shiro 提供了 base64和 16
进制字符串编码/解码的 API支持,方便一些编码解码操作。 Shiro内部的一些数据的存储/表示都使用了
base64和 16 进制字符串。

下面两端代码分别对其进行演示

Stringstr = "hello"; 

Stringbase64Encoded = Base64.encodeToString(str.getBytes()); 

Stringstr2 = Base64.decodeToString(base64Encoded); 

Assert.assertEquals(str,str2);

通过如上方式可以进行 base64编码/解码操作

Stringstr = "hello"; 

Stringbase64Encoded = Hex.encodeToString(str.getBytes()); 

Stringstr2 =newString(Hex.decode(base64Encoded.getBytes())); 

Assert.assertEquals(str,str2);

通过如上方式可以进行 16
进制字符串编码/解码操作

Hash存储

散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如 MD5、SHA等。一般进行散列时最好提供一个 salt(盐),比如加密密码“admin”,产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,可以到一些
md5解密网站很容易的通过散列值得到密码“admin”,即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,如用户名和 ID(即盐);这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解。

Stringstr = "hello"; 

Stringsalt = "123"; 

Stringmd5 =new Md5Hash(str, salt).toString();//还可以转换为  toBase64()/toHex()

如上代码通过盐“123”MD5散列“hello”。另外散列时还可以指定散列次数,如 2次表示:md5(md5(str)):“new
Md5Hash(str, salt, 2).toString()”

Stringstr = "hello"; 

Stringsalt = "123"; 

Stringsha1 =new Sha256Hash(str, salt).toString();

使用 SHA256
算法生成相应的散列数据,另外还有如 SHA1、SHA512算法。

Shiro 还提供了通用的散列支持:

Stringstr = "hello"; 

Stringsalt = "123"; 

//内部使用MessageDigest 

StringsimpleHash =new SimpleHash("SHA-1", str, salt).toString();

通过调用 SimpleHash 时指定散列算法,其内部使用了 Java的 MessageDigest
实现。为了方便使用,Shiro提供了 HashService,默认提供了 DefaultHashService实现

DefaultHashServicehashService =new DefaultHashService(); //默认算法 SHA-512 

hashService.setHashAlgorithmName("SHA-512");

hashService.setPrivateSalt(newSimpleByteSource("123"));//私盐,默认无

hashService.setGeneratePublicSalt(true);//是否生成公盐,默认false 

hashService.setRandomNumberGenerator(new  SecureRandomNumberGenerator());//用于生成公盐。默认就这个

hashService.setHashIterations(1);//生成 Hash 值的迭代次数

HashRequestrequest =new HashRequest.Builder() 

.setAlgorithmName("MD5").setSource(ByteSource.Util.bytes("hello"))

.setSalt(ByteSource.Util.bytes("123")).setIterations(2).build();

Stringhex =hashService.computeHash(request).toHex();

加密存储

Shiro 还提供对称式加密/解密算法的支持,如 AES、Blowfish等;当前还没有提供对非对称加密/解密算法支持,未来版本可能提供。

AES 算法实现:

AesCipherServiceaesCipherService =new AesCipherService(); 

aesCipherService.setKeySize(128);//设置 key 长度

//生成 key 

Keykey=aesCipherService.generateNewKey(); 

Stringtext = "hello"; 

//加密

StringencrptText =

aesCipherService.encrypt(text.getBytes(),key.getEncoded()).toHex(); 

//解密

Stringtext2 = 

newString(aesCipherService.decrypt(Hex.decode(encrptText),key.getEncoded()).getBytes()); 

Assert.assertEquals(text, text2);

密码的验证

使用“密码的存储”章节中其中一种存储方式存储密码之后,接下来就是登陆时密码的验证.

该过程主要涉及到两个问题:

(1)    让Shiro知道数据库中存储的密码是通过什么方式存储的?

可以在指定比较器时进行设置

(2)    让Shiro知道如何比对数据库与登录时的密码?

Shiro主要通过CredentialsMatcher的子类来实现密码的对比,Shiro已经实现了比较常见的Matcher,例如Md5CredentialsMatcher,Sha256CredentialsMatcher等等,如果Shiro提供的Matcher不能满足需求,还可以自定义Matcher.

Spring集成Shiro密码验证实例

本小节以Spring集成Shiro为基础,介绍如何使用MD5对密码进行加密,添加密码加密功能需要经过以下三步

保存密码

作为密码的数据源头,首先要确保在密码保存时就使用MD5加密

在Spring的Controller对应的方法中,使用以下方法保存密码

@RequestMapping("/setting/user/add")
  public String addUser(@Valid User user, BindingResult result, Map<String, Object> model,
      @RequestParam(value = "action") String action) {
    String cryptedPwd = new Md5Hash(user.getPwd()).toString();
    user.setPwd(cryptedPwd);
    userService.saveUser(user);
    return "redirect:/setting/user/" + user.getName();
  }

配置Matcher

当数据库中存的是MD5形式的密码后,就要告诉shiro如何对登陆时输入的密码进行对比,在这里采用默认的HashedCredentialsMatcher作为比较器

Shiro-config.xml配置如下

<!—在自定义的Realm中配置Matcher,并指定加密算法-->

         <beanid="customerRealm" class="com. test.security.CustomerRealm">

                   <propertyname="credentialsMatcher">

                            <beanclass="org.apache.shiro.authc.credential.HashedCredentialsMatcher">

                                     <propertyname="hashAlgorithmName" value="MD5" />

                            </bean>

                   </property>

         </bean>

密码校验

对于CustomerRealm而言,不需要关心密码是如何被匹配的,只需要将用户输入的密码传入AuthenticationInfo对象中即可

@Override

  protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)

     throws AuthenticationException {

   // 获取基于用户名和密码的令牌,authcToken是从LoginController里面//currentUser.login(token)传过来的

   UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

   User user = userService.findUserByName(token.getUsername());

    if(null != user) {

     AuthenticationInfo authcInfo =

         new SimpleAuthenticationInfo(user.getName(), user.getPwd(),user.getName());

     this.setSession(GCloudConstant.CURRENT_USER,user.getName());

     return authcInfo;

    }else {

     return null;

    }

  }

将 Shiro 作为应用的权限基础 五:密码的加密/解密在Spring中的应用,布布扣,bubuko.com

时间: 06-14

将 Shiro 作为应用的权限基础 五:密码的加密/解密在Spring中的应用的相关文章

将 Shiro 作为应用的权限基础 五:SpringMVC+Apache Shiro+JPA(hib

点击链接加入群[JavaEE(SSH+IntelliJIDE+Maven)]:http://jq.qq.com/?_wv=1027&k=L2rbHv 将 Shiro 作为应用的权限基础 五:SpringMVC+Apache Shiro+JPA(hibernate)整合配置 配置web.xml,applicationContext.xml, spring-mvc.xml,applicationContext-shiro.xml,而且都有详细的说明. web.xml是web项目最基本的配置文件,看这

将 Shiro 作为应用的权限基础 五:SpringMVC+Apache Shiro+JPA(hibernate)整合配置

配置web.xml,applicationContext.xml, spring-mvc.xml,applicationContext-shiro.xml,而且都有详细的说明. Web.xml是web项目最基本的配置文件,看这个配置,可以快速知道web项目使用什么框架,它就像一个面板,切入我们想用的插件. applicationContext.xml是spring的基本配置,主要配置数据源.JPA实体管理器工厂.事务 spring-mvc.xml是SpringMVC的配置, applicatio

将 Shiro 作为应用的权限基础 二:基于SpringMVC实现的认证过程

认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的“实体/凭证”组合便是“用户名/密码”组合. 一.认证过程 1.收集实体/凭据信息 Java代码 UsernamePasswordToken token = new UsernamePasswordToken(username, password); token.setRememberMe(true); UsernamePasswordToken支

将 Shiro 作为应用的权限基础 四:shiro的配置说明

Apache Shiro的配置主要分为四部分: SecurityManager的配置 URL过滤器的配置 静态用户配置 静态角色配置 其中,由于用户.角色一般由后台进行操作的动态数据,比如通过@RequiresRoles注解控制某方法的访问,因此Shiro配置一般仅包含前两项的配置. SecurityManager的配置:  [html] view plaincopy <span style="font-size:18px"><!--shiro securityMan

将 Shiro 作为应用的权限基础 一:shiro的整体架构

将 Shiro 作为应用的权限基础 一:shiro的整体架构 近来在做一个重量级的项目,其中权限.日志.报表.工作量由我负责,工作量还是蛮大的,不过想那么多干嘛,做就是了. 这段时间,接触的东西挺多,比如apacheshiro,spring data,springside.DWZ等,java的东西好多,学过ssh就像当初学过三层一样. 下面看看这个安全框架吧 一.什么是Shiro Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证.授权.管理会话以及密码加密.如下是它所具有的特点:

将 Shiro 作为应用的权限基础 三:基于注解实现的授权认证过程

授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限. 如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限等等. 一.用户权限模型 为实现一个较为灵活的用户权限数据模型,通常把用户信息单独用一个实体表示,用户权限信息用两个实体表示. 用户信息用 LoginAccount 表示,最简单的用户信息可能只包含用户名 loginName 及密码 password 两个属性.实际应用中可能会包含用户是否被禁用,用户信息是否过期等信息. 用户权限信息用 Role 与 Per

将 Shiro 作为应用的权限基础

Shiro 是 Java 世界中新近出现的权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势.本文介绍了 Shiro 的关键概念和权限模型,同时给出了 Shiro 以及 Grails Shiro Plugin 的使用示例.在阅读本文的过程中,读者可以充分的体会到 Shiro 的魅力. 前言 Shiro 是 JAVA 世界中新近出现的权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大功

业务逻辑:五、完成认证用户的动态授权功能 六、完成Shiro整合Ehcache缓存权限数据

一. 完成认证用户的动态授权功能 提示:根据当前认证用户查询数据库,获取其对应的权限,为其授权 操作步骤: 在realm的授权方法中通过使用principals对象获取到当前登录用户 创建一个授权信息对象 根据用户查询角色列表,并遍历角色列表 在循环体中将角色关键字添加到授权信息对象的角色属性中 根据用户查询权限列表,并遍历权限列表 在循环体中将权限关键字添加到授权信息对象的权限属性中 在角色与权限service类的根据用户查询角色与权限方法中判断用户是否为系统管理员 如果是系统管理员就查询出所

【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限

开发环境搭建参见<[原]无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页> 需求: ① 除了登录页面,在地址栏直接访问其他URL,均跳转至登录页面 ② 登录涉及帐号和密码,帐号错误提示帐号错误,密码错误提示密码错误 ③ 登录成功跳转至首页,首页显示登录者帐号信息,并有注销帐号功能,点击注销退出系统 ------------------------------------------------------------------