shiro+密码匹配器验证登陆

1.先上工具类MD5Util   目前真正用到的是直接MD5加密的方法   未使用自定义加工密码加密

package cn.cjq.util;

import cn.cjq.entity.User;

import java.security.MessageDigest;import java.util.Random;

public class MD5Util {

/**    * 加工密码,和登录一致。    * @param user    * @return    */   public static User md5Pswd(User user){      //密码为   username + ‘#‘ + password,然后MD5      user.setPassword(md5Pswd(user.getUsername(),user.getPassword()));      return user;   }   /**    * 字符串返回值    * @param email    * @param pswd    * @return    */   public static String md5Pswd(String email ,String pswd){      pswd = String.format("%s#%s", email,pswd);      pswd = getMD5(pswd);      return pswd;   }

/**    * MD5 加密    * @param str    * @return    * @throws Exception    */   public static String  getMD5(String str) {      MessageDigest messageDigest = null;      try {         messageDigest = MessageDigest.getInstance("MD5");         messageDigest.reset();         messageDigest.update(str.getBytes("UTF-8"));      } catch (Exception e) {         System.out.println("MD5转换异常!message:%s"+e.getMessage());      }

byte[] byteArray = messageDigest.digest();      StringBuffer md5StrBuff = new StringBuffer();      for (int i = 0; i < byteArray.length; i++) {         if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)            md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));         else            md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));      }      return md5StrBuff.toString();   }

/**    * 获取随机的数值。    * @param length   长度    * @return    */   public static String getRandom620(Integer length){      String result = "";      Random rand = new Random();      int n = 20;      if(null != length && length > 0){         n = length;      }      boolean[]  bool = new boolean[n];      int randInt = 0;      for(int i = 0; i < length ; i++) {         do {            randInt  = rand.nextInt(n);

}while(bool[randInt]);

bool[randInt] = true;         result += randInt;      }      return result;   }

/**    * 加密解密算法 执行一次加密,两次解密    */   public static String convertMD5(String inStr){

char[] a = inStr.toCharArray();      for (int i = 0; i < a.length; i++){         a[i] = (char) (a[i] ^ ‘t‘);      }      String s = new String(a);      return s;

}

}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.密码加密实例   注册时会使用(只需要将加密的密码存入数据库),传给UsernamePasswordToken的密码参数是未加密的密码,由密码匹配器去自动匹配

/**    * 注册 && 登录    * @param vcode       验证码    * @return    */   @RequestMapping(value="subRegister")   @ResponseBody   @SystemControllerLog(description = "用户注册登陆")   public Response subRegister(@RequestParam(value="userName",required=false,defaultValue="") String userName,                        @RequestParam(value="passWord",required=false,defaultValue="") String passWord,                        @RequestParam(value="realname",required=false,defaultValue="") String realname,                        @RequestParam(value="userType",required=false,defaultValue="") String userType,                        @RequestParam(value="vcode",required=false,defaultValue="") String vcode)throws Exception{      //手机号不合法      if(!isMobileNO(userName)){         return new Response(ExceptionMsg.UserNameError);      }      //用户名已存在      User user = userServiceImpl.findByUserName(userName);      if(null != user){         return new Response(ExceptionMsg.UserNameUsed);      }      //验证码错误      KeyValue data=(KeyValue)stringRedisServiceImpl.get(userName);      if(data==null){         return new Response(ExceptionMsg.VcodeNotExists);      }else if(!data.getValue().equals(vcode)){         return new Response(ExceptionMsg.VcodeError);      }      //把密码md5      String password = MD5Util.getMD5(passWord);      //注册      User newuser =new User();      String uuid = UUID.randomUUID().toString().replaceAll("-", "");      newuser.setUerid(uuid);      newuser.setAddtime(new Date());      newuser.setCreateperson(uuid);      newuser.setUsername(userName);      newuser.setEnditime(new Date());      newuser.setIsdelete(0);      newuser.setStatus("1");      newuser.setPassword(password);      newuser.setRealname(realname);      newuser.setPhone(userName);      newuser.setDifference(1);      userServiceImpl.insertuser(newuser);        //登陆验证      UsernamePasswordToken token = new UsernamePasswordToken(userName,passWord,false);      SecurityUtils.getSubject().login(token);       Session sessions = SecurityUtils.getSubject().getSession();      sessions.setAttribute("user",newuser );      //清理内存      stringRedisServiceImpl.remove(userName);      return new Response(ExceptionMsg.SUCCESS);}--------------------------------------------------------------------------------------------------------------------------3.shiro.xml配置密码匹配器   两个bean  配置在自定义的realm里属性hashIterations的值目前为1,代表加密一次,其他值未试过,不明觉厉,待续
<!-- 凭证匹配器--><bean id="credentialsMatcher" class="cn.cjq.util.shiro.RetryLimitHashedCredentialsMatcher">   <constructor-arg ref="cacheManager"/>   <property name="hashAlgorithmName" value="md5"/>   <property name="hashIterations" value="1"/>   <property name="storedCredentialsHexEncoded" value="true"/></bean>
<bean id="myShiroRealm" class="cn.cjq.util.shiro.UserRealm">   <!-- 配置密码匹配器 -->   <property name="credentialsMatcher" ref="credentialsMatcher"/>   <property name="cachingEnabled" value="true"/>   <property name="authenticationCachingEnabled" value="true"/>   <property name="authenticationCacheName" value="authenticationCache"/>   <property name="authorizationCachingEnabled" value="true"/>   <property name="authorizationCacheName" value="authorizationCache"/></bean>--------------------- ----------------------------------------------------------------------------------------------------------------4.自定义的密码匹配器  目前使用的md5
package cn.cjq.util.shiro;

import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.ExcessiveAttemptsException;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheManager;

import java.util.concurrent.atomic.AtomicInteger;

public class RetryLimitHashedCredentialsMatcher extends      HashedCredentialsMatcher {   private Cache<String, AtomicInteger> passwordRetryCache;

public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {        passwordRetryCache = cacheManager.getCache("passwordRetryCache");    }

@Override    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {        String username = (String)token.getPrincipal();        //retry count + 1        AtomicInteger retryCount = passwordRetryCache.get(username);        if(retryCount == null) {            retryCount = new AtomicInteger(0);            passwordRetryCache.put(username, retryCount);        }        if(retryCount.incrementAndGet() > 5) {            //if retry count > 5 throw            throw new ExcessiveAttemptsException();        }

boolean matches = super.doCredentialsMatch(token, info);        if(matches) {            //clear retry count            passwordRetryCache.remove(username);        }        return matches;    }}

原文地址:https://www.cnblogs.com/1234cjq/p/8143745.html

时间: 2024-08-29 19:21:03

shiro+密码匹配器验证登陆的相关文章

关于 Shiro 的权限匹配器和过滤器

项目源码:https://github.com/weimingge14/Shiro-project演示地址:http://liweiblog.duapp.com/Shiro-project/login 上一节,我们实现了自定义的 Realm,方式是继承 AuthorizingRealm这个抽象类,分别实现认证的方法和授权的方法. 这一节实现的代码的执行顺序: 1.Shiro定义的过滤器和自定义的过滤器,在自定义的过滤器中执行 Subject对象的判断是否具有某项权限的方法 isPermitted

sql server 2008 r2 修改sa密码 通过sql server 身份验证登陆

sql server 2008 r2 修改sa密码 通过sql server 身份验证登陆 解决方法如下 通过windows 身份验证登陆后, 首先选中服务器(右键)->属性 ->安全性->服务器身份验证修改为"SQL SERVER和WINDOWS身份验证模式"其次展开服务器上的"安全性"->登陆名->选中SA登陆帐号(右键)->状态->登陆修改为启用, 并在常规选项中修改密码 确认后重启 sel server sql se

Centos7+Openvpn使用用户及密码验证登陆

我们上一篇文章介绍了Centos7+Openvpn使用证书验证登陆介绍,今天我们介绍Centos7+Openvpn使用用户及密码登陆验证,具体就补多少了,环境还是基于上一篇的更改来完成. 我们使用Centos7+Openvpn使用用户及密码登陆验证小下载一个验证脚本来完成用户验证登陆. http://openvpn.se/files/other/checkpsw.sh #!/bin/sh ######################################################

用WPF写一个登录界面,我想在输入完密码后按回车就能够验证登陆,而不需要用鼠标单击登陆按钮

原文:用WPF写一个登录界面,我想在输入完密码后按回车就能够验证登陆,而不需要用鼠标单击登陆按钮 在wpf中,将按钮的IsDefault设置为true ???? 原文地址:https://www.cnblogs.com/lonelyxmas/p/9345580.html

Apach Shiro 密码加密过程(明文生成密码过程)详细解析

前言: 最近再项目当中使用的ApachShiro安全框架,对于权限和服务器资源的保护都有一个很好的管理.前期主要参考的文章有 项目中设计密码的加盐处理以及二次加密问题,跟着断点 一步步揭开Apach Shiro 的神秘面纱 数据库: 这里我们就用最简单的admin + 123456(加密前的密码) 来做测试 ShiroConfig 配置 /** * 凭证匹配器 告诉 * @return */ @Bean public HashedCredentialsMatcher hashedCredenti

验证登陆信息的合法性

大多系统登录模块都会接收用户通过键盘输入的登录信息,这些登录信息将会被登陆模块验证,如果使用的是指定的用户名与密码,则允许程序登陆,否则将用户拒之门外.本范例通过 if…else 语句进行多条件判断来实现登陆信息的验证. 在项目中创建 CheckLogin 类,在该类的主方法中接收用户输入的登陆用户名与登陆密码,然后通过 if 条件语句分别判断用户名和密码,并输出登陆验证结果.代码如下: import java.util.Scanner; public class CheckLogin { pu

android客户端向服务器端验证登陆方法的实现1

遇到的问题:一个条件查询与多个条件查询,所用到的方式不一样 参考文档: http://www.oschina.net/question/1160609_133366    mybatis多条件查询的一个错误 解决方案如下: 利用序列号的方式解决多个参数的查询问题.对象与数据库关系的映射层. 层次结构如下: 首先定义model层里面的Userlist类,这是和我们后台mysql里面的表是一一对应的,然后定义UserlistMapper类,这个类主要是用来封装一些个方法,比如说增删改查等.其实现通过

android客户端向服务器端验证登陆方法的实现2

一.在上一篇文章中,我只是提到了其中一种方法来实现登陆 大家可以参见: http://www.apkbus.com/android-45004-1-1.html      android获取web服务器端session并验证登陆 http://blog.csdn.net/cainiao123hack/article/details/8255848   服务器端向Android客户端传值--登录实现 http://zhidao.baidu.com/link?url=8g9EWhyUkUgUr1dh

saltstack 自动化运维神器(三)节点组及复合匹配器

saltstack实现远程配置管理功能首先是要先匹配到对应的target minion,然后才会将命令发送到匹配到的minion上去执行.这里介绍两种比较强大的匹配方法,一是创建节点组:二是使用复合匹配器. 节点组将不同的主机分配到不同的组中去,便于实现主机的集中化管理,接下来首先看salt分组功能的实现. 要使用salt的分组功能,需要在master节点上进行配置,配置的方式有两种: (1).将分组的信息写在master的主配置文件 (2).将分组的信息写在一个单独的配置文件中,然后主配置文件