Shiro密码加密加盐

一、Shiro配置添加:

package com.how2java.tmall.config;
 
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import com.how2java.tmall.realm.JPARealm;
 
@Configuration
public class ShiroConfiguration {
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }
     
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(getJPARealm());
        return securityManager;
    }
 
    @Bean
    public JPARealm getJPARealm(){
        JPARealm myShiroRealm = new JPARealm();
        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return myShiroRealm;
    }
    
    //密码加密后的匹配机制设置, 若不设置, 则无法解析加密后的密码了
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //加密方式 采取 md5 方式
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        //加密次数 加密2次
        hashedCredentialsMatcher.setHashIterations(2);
        return hashedCredentialsMatcher;
    }
}

注:不仅要添加解析密码加密的配置类, 还要在 JPARealm 对象 myShiroRealm 中设置 :myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());

二、 登陆调用验证方法时加上盐值(否则缺少盐值则无法解析加密密码了):

package com.how2java.tmall.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.how2java.tmall.pojo.User;
import com.how2java.tmall.service.UserService;

public class JPARealm extends AuthorizingRealm{
	
	@Autowired
	private UserService userService;
	
	//授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo s = new SimpleAuthorizationInfo();
		return s;
	}
	
	//验证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upt = (UsernamePasswordToken) token;
		String userName = upt.getUsername();
		User user = userService.getByName(userName);
		String dBpassword = user.getPassword();
		String salt = user.getSalt();
		
		return new SimpleAuthenticationInfo(userName/*携带的信息*/, dBpassword/*数据库中的密码, 会自动与登录的密码比较*/, ByteSource.Util.bytes(salt)/*盐值*/, getName());
	}

}

三、登陆时,将账号与密码生成令牌调用shiro函数:

public Result login(@RequestBody User bean, HttpServletSession session){
		System.out.println("bean.getAccount()" + bean.getAccount());
		System.out.println("bean.getPassword()" + bean.getPassword());
		
		String account = bean.getAccount();
		account = HtmlUtils.htmlEscape(account);
		
		//获取subject
		Subject subject = SecurityUtils.getSubject();
		//将前端账号和密码包装成令牌
		UsernamePasswordToken token = new UsernamePasswordToken(account, bean.getPassword());
		
		try{
			/**
			 * 传入令牌,令牌中有前端输入的账号密码,调用shiro的配置函数与数据库的账号密码比对
			 * 如果比对错误将抛出异常, 正确则继续执行
			 */
			subject.login(token);
			User _user = userService.checkLogin(bean);
			//设置session
			session.setAttribute("user", _user);
			return Result.success();
		}
		catch(AuthenticationException e){
			String msg = "账号或密码错误";
			return Result.fail(msg);
		}
	}

三、 注册时的密码加密:

	@PostMapping("foreregister")
	public Object register(@RequestBody User user){
		String name = user.getName();
		String password = user.getPassword();
		//对用户注册的昵称进行转义,避免SQL注入攻击
		name = HtmlUtils.htmlEscape(name);
		user.setName(name);
		
		boolean exit = userService.IsExit(name);
		if(exit){
			String message = "用户名已存在,请使用其他用户名";
			return Result.fail(message);
		}
		
		//盐值
		String salt = new SecureRandomNumberGenerator().nextBytes().toString();
		//加密次数
		int times = 2;
		//加密方式
		String algorithmName = "md5";
		//初始化加密密码
		String encodedPassword = new SimpleHash(algorithmName/*加密方式*/, password, salt, times).toString();
	
		user.setSalt(salt);
		user.setPassword(encodedPassword);
		userService.add(user);
		
		return Result.success();
	}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值