您的当前位置:首页正文

Springboot实现 shiro+Mybatis+MD5+sale+Hash散列认证授权

2024-11-29 来源:个人技术集锦

牢记

  • SecurityManager:安全管理器
  • ShiroFilterFactoryBean:过滤器工厂
  • Realm:Shiro从Realm获取安全数据(用户、角色、权限),
  • 常用过滤器

直接跳转







:重点为 登录方法


SpringBoot 目录结构

pom.xml
    <dependencies>
<!--        thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
<!--        shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.7.1</version>
        </dependency>
<!--        jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
<!--        web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--        mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
ShrioConfig
@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(webSecurityManager());
        Map<String, String> filterMap = new LinkedHashMap<>(); //查询源码,发现需要Map集合
        filterMap.put("/all","anon");
        filterMap.put("/r/**","authc");
        factoryBean.setFilterChainDefinitionMap(filterMap);
        // 默认登录URL为null,需设置
        factoryBean.setLoginUrl("/");
        return factoryBean;
    }
    @Bean
    public DefaultWebSecurityManager webSecurityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userReaml());
        return securityManager;
    }
     @Bean
    public UserReaml userReaml(){
        UserReaml userReaml = new UserReaml();
		//创建 散列凭证匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5"); //设置 MD5散列算法
        credentialsMatcher.setHashIterations(1024); // 迭代次数1024  与service中的对应
        //修改凭证校验匹配器
        userReaml.setCredentialsMatcher(credentialsMatcher);
        return userReaml;
    }
}

UserRealm
public class UserReaml extends AuthorizingRealm {

    @Autowired
    UserService userService;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行授权");
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        System.out.println("认证 -> doGetAuthorizationInfo");
        User user = userService.findByName(userToken.getUsername());
        if (ObjectUtils.isArray(user))
            return null;
        //密码自动认证,这里先部分省略   参数为:当前用户的姓名,密码,盐,认证名
        return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), ByteSource.Util.bytes(user.getPermission()),this.getName());
    }
}

Mapper
@Repository
@Mapper
public interface UserMapper {

    @Select("select * from user where username=#{username}")
    public User findByName(String username);

    @Insert("insert into user values(null,#{username},#{password},#{permission})")
    @Options(useGeneratedKeys = true,keyProperty = "id") //获取自增主键
    void insert(User user);
}
UserService
@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    public void addUser(User user){
        String sale = SaleUtils.getSale(8); //获取盐
        // md5 + sale + hash散列
        Md5Hash md5Hash = new Md5Hash(user.getPassword(),sale,1024);
        user.setPermission(sale);
        user.setPassword(md5Hash.toHex()); //转16进制
        userMapper.insert(user);
    }

    public User findByName(String username) {
        return userMapper.findByName(username);
    }
}
SaleUtils
public class SaleUtils {

    public static String getSale(int n){
        char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*".toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < n; i++) {
            char c = chars[new Random().nextInt(chars.length-1)];
            sb.append(c);
        }
        return sb.toString();
    }

}
UserController
@RestController
public class UserController {

    @Autowired
    UserService userService;
    @RequestMapping("/regirect")
    public String regirect(User user){
        if (StringUtils.isEmpty(user.getUsername())&&StringUtils.isEmpty(user.getPassword()))
            return "输入错误";
        try {
            userService.addUser(user);
            return "注册成功";
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @RequestMapping("/logout")
    public String logout(){
        //退出
        SecurityUtils.getSubject().logout();
        return "退出成功";
    }

    @PostMapping("/login")
    public String login(User user){
        Subject subject = SecurityUtils.getSubject();
        try {
            /**
             * 执行login()方法时会将token传送到自定义realm的授权方法中,
             */
            subject.login(new UsernamePasswordToken(user.getUsername(), user.getPassword())); //执行登录的方法
            return "登录成功";
        } catch (UnknownAccountException e){
            return "用户名错误";
        } catch (IncorrectCredentialsException e){
            return "密码错误";
        }

    }

    @RequestMapping("/r/1")
    public String r1(){
        return "访问r/1";
    }
    @RequestMapping("/r/2")
    public String r2(){
        return "访问r/2";
    }
    @RequestMapping("/r/3")
    public String r3(){
        return "访问r/3";
    }

    @RequestMapping("/all")
    public String r4(){
        return "公共资源";
    }
}

更多查看 gitee

显示全文