Shiro框架的登录注册、使用MD5加盐值加密

Shiro安全框架简单实现登录注册

自己积累的一些shiro和springboot的使用和笔记,观看【遇见狂神说】做的笔记。

登录流程

pom.xml

  <!--shiro安全框架-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>

Controller层接收数据

    @Autowired
    private UserService userService;
    @PostMapping("/Controller")
    public Integer Login(String username, String password){

        //shiro获取用户认证
        //获取当前的用户
        Subject subject= SecurityUtils.getSubject();
        //封装用户的登录数据
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        try{
            subject.login(token);//执行登录方法,如果没有异常就说明ok,这里需要try/catch
            System.out.println("登陆成功");
            Integer id = userService.findIdByUsername(username);
            return id;//没有报错的情况,返回正确界面
        }catch(UnknownAccountException uae){//不存在账户报错
            System.out.println("不存在账户报错");
            return 0;
        }catch(IncorrectCredentialsException ice){//密码错误
            System.out.println("密码错误");
            return 0;
        }catch(LockedAccountException lae){//用户被锁定了
            return 0;
        }catch(AuthenticationException ae) {//认证异常
            System.out.println("认证异常");
            return 0;
        }
    }
    
    @RequestMapping("/errorLogin")
    public Integer errorLogin(){
        System.out.println("跳转错误界面");
        return null;
    }

ShiroConfig类

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/*
shiro的配置类
 */
@Configuration
public class ShiroConfig {
    /*
    创建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean bean =new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(securityManager);
        //添加shiro的内置过滤器,完成登录的拦截
        /**
         anon:无需认证就可以登录
         authc:必须认证了才能登录
         user:必须拥有记住我功能才能使用
         perms:拥有对某个资源的权限才能使用
         role:拥有某个角色条件才能使用
         **/
        Map<String,String> filterMap =new LinkedHashMap<String,String>();
        filterMap.put("/Login/*","anon");
        filterMap.put("/user/*","authc");
        filterMap.put("/*","anon");
        bean.setFilterChainDefinitionMap(filterMap);
        //设置登录的请求
        bean.setLoginUrl("/errorLogin");
        //也可以处理其他请求
        //处理未授权401的请求,跳转到controller层的noauth方法
        bean.setUnauthorizedUrl("/noauth");
        return bean;
    }


    /*
    创建DefaultWebSecurityManager
     */
    //第二步,DefaultWebSecurityManager
    //关联realm
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getdefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager =new DefaultWebSecurityManager();
        //关联
        securityManager.setRealm(userRealm);
        return securityManager;
    }


    /*
    创建Realm
     */
    @Bean(name = "userRealm")
    public UserRealm userRealm(){
        UserRealm realm = new UserRealm();
        //设置加密的方式(一定要设置自定义的加密方式)
        realm.setCredentialsMatcher(hashedCredentialsMatcher());
        return realm;
    }
    
    //MD5加密
    @Bean("hashedCredentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //指定加密方式为MD5
        credentialsMatcher.setHashAlgorithmName("md5");
        //加密次数
        credentialsMatcher.setHashIterations(1024);
        //是否存储为16进制(一定要开启)
//        将setStoredCredentialsHexEncoded设置为true,则需要使用toHex()进行转换成字符串,默认使用的是toBase64()
        credentialsMatcher.setStoredCredentialsHexEncoded(true);
        return credentialsMatcher;
    }
}

UserRealm

import com.login.register.domain.User;
import com.login.register.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
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.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

public class UserRealm  extends AuthorizingRealm {

    @Autowired
    UserService userService;
//    执行授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        SimpleAuthorizationInfo info =new SimpleAuthorizationInfo();
        info.addStringPermission("user.add");
        //拿到当前的登陆对象
        Subject subject = SecurityUtils.getSubject();
        User currentUser =(User)subject.getPrincipal();
        //添加权限,perem为数据库中的权限
        info.addStringPermission(currentUser.getPerms());
        return info;
    }
//认证逻辑
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken userToken=(UsernamePasswordToken)token;
        String username = userToken.getUsername();
//        查询是否存在该id
        User user = userService.findByUsername(username);
        if (user==null){
            return null;
        }
        String password = user.getPassword();
        //盐值
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername());//使用账号作为盐值
        String realmName = getName();
//        System.out.println(password);
        return new SimpleAuthenticationInfo(user,password,credentialsSalt,realmName);

    }
}

注册

注册逻辑很简单,只是在密码加密的部分有改动。其它验证部分

添加MD5加密方法

import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;

public class MD5 {    //添加MD5加密方法
	//输入相对应的盐值和密码,可再添加输入自定义加密次数的方法
    public static String SysMd5(String username,String password) {
        String hashAlgorithmName = "MD5";//加密方式
        ByteSource salt = ByteSource.Util.bytes(username);//以账号作为盐值
        int hashIterations = 1024;//加密1024次
        String newPassword= new SimpleHash(hashAlgorithmName,password,salt,hashIterations).toHex();
        return newPassword;
    }
}

Service层验证办法

  //通过输入的用户名来查询账号名是否已存在
        Integer id = userDao.findIdByUsername(username);
//        System.out.println(id);
        //不存在即可注册
        if (id == null) {
            //将账号密码封装至user
            User user = new User();
            user.setUsername(username);
            //通过MD5加密保存
            try {
                String md5password = MD5.SysMd5(username, password);
                user.setPassword(md5password);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //将数据插入到数据库
            userDao.insertUser(user);

            return user;
        }else {
            return null;
        }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Shiro框架是一个强大的安全框架,可以实现身份认证、授权和加密等功能。以下是一个使用Shiro框架实现登录接口的示例代码: ``` import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class LoginController { @PostMapping("/login") public String login(@RequestBody User user) { String username = user.getUsername(); String password = user.getPassword(); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { subject.login(token); return "登录成功"; } catch (AuthenticationException e) { return "用户名或密码错误"; } } } ``` 在上述代码中,我们使用Shiro框架的Subject对象,该对象表示当前用户的安全操作。我们首先获取Subject对象,然后使用用户名和密码创建一个UsernamePasswordToken对象,将其传递给Subject对象的login方法进行身份认证。 如果身份认证成功,login方法不会抛出任何异常,我们可以在返回中返回登录成功的信息。如果身份认证失败,login方法会抛出AuthenticationException异常,我们可以在catch块中处理该异常,返回用户名或密码错误的信息。 需要注意的是,我们在上述代码中使用了@RestController注解,该注解表示该类中的所有方法都会返回JSON格式的数据。我们还使用了@PostMapping注解,该注解表示该方法只接受POST请求。在实际开发中,我们可以根据需要修改这些注解的参数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值