Shiro 整合springboot

这里写目录标题

第一步 导入依赖

 <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId>
            <version>1.7.0</version>
        </dependency>

其他的 包自行导入 如 数据库等等

第二步 建立shiroconfig 文件

@Configuration
public class ShiroConfig {

    //创建 shirofilter  拦截所有的请求

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //给filter  设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //配置哪些路径需要 受限
        Map<String,String> map =new HashedMap();
        map.put("/user/login","anon"); //anon  表示为公共资源
        map.put("/index.jsp","authc"); //authc 表示这个资源需要进行认证和授权
        map.put("/user/register.jsp","anon");
        map.put("/register.jsp","anon");
        //设置默认的认证界面路径
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");

        //将设置好的 map  写入filter
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //创建安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
        //给安全管理器  设置 realm
        defaultWebSecurityManager.setRealm(realm);
        return defaultWebSecurityManager;
    }


    //创建自定义的realm
   @Bean
    public Realm getRealm(){
       CusterRealm custerRealm=new CusterRealm();
       //修改凭证校验匹配器
       HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
       //设置算法
       matcher.setHashAlgorithmName("MD5");
       //设置散列次数  与你进行加密的数据对应
       matcher.setHashIterations(1024);
       custerRealm.setCredentialsMatcher(matcher);

       //开启缓存管理  可以不管  这是练习的笔记
      // custerRealm.setCacheManager(new EhCacheManager());
       //custerRealm.setCachingEnabled(true); //开启全局缓存
       //custerRealm.setAuthenticationCachingEnabled(true); //开启认证缓存

       //custerRealm.setAuthorizationCachingEnabled(true); //开启授权缓存

       return custerRealm;
   }

}

第三步 创建自定义的realm

public class CusterRealm  extends AuthorizingRealm {
    @Autowired   //这个是  调用数据库的操作
    
    UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        String principal =(String) principalCollection.getPrimaryPrincipal();
        System.out.println(principal+" 进入doGetAuthorizationInfo 方法查询权限");
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        if("zyc".equals(principal)){
            simpleAuthorizationInfo.addRole("user");
        }

        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
       String principal= (String) authenticationToken.getPrincipal();
        System.out.println(userService);
        User user=userService.findByname(principal);
       if(user!=null) {
           //参数一: 数据库中正确的 用户名  参数二数据库中的密码  参数三随机盐的数值   参数四 realm的name
           //密码的校验 有默认的方法进行比较  不需要自己进行定义
           return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());
       }
       return  null;
    }
}

第四步:关于加密和解密:

加密

 public void register(User user) {
        //进行MD5 加密  用了盐
        String salt = SaltUtils.getsalt(4);  //SaltUtils.getsalt自己建立的 随机获取四个符号
        //散列次数1024 与 您在config 的进行匹配
        Md5Hash md5Hash=new Md5Hash(user.getPassword(),salt,1024);
        //把salt  存进数据库 不然登录无法认证
        user.setSalt(salt);
        user.setPassword(md5Hash.toHex());
        userMapper.save(user);

    }

//加密获取的随机数代码

public class SaltUtils {

    public static String getsalt(int n){
        String s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()";
        char[] chars = s.toCharArray();

        StringBuilder sb=new StringBuilder();
        for (int i = 0; i < n; i++) {

            sb.append(chars[new Random().nextInt(s.length())]);
        }
        return sb.toString();
    }


}

解密:

首先 在 认证的时候 传输盐的值:
Shiro 整合springboot
然后在config 里面 传输 散列次数和采用的算法匹配器:
Shiro 整合springboot

补充 :登录与登出:

 @GetMapping("/logout")
    public String logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "redirect:/login.jsp";
    }

    @PostMapping("/login")
    public String login(@RequestParam("name") String name,@RequestParam("password") String password){
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(new UsernamePasswordToken(name,password));
            return "redirect:/index.jsp";
        }catch (UnknownAccountException e){
            e.printStackTrace();
            System.out.println("用户名不存在");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System.out.println("密码错误");
        }
        return "redirect:/login.jsp";
    }
上一篇:SpringBoot整合Shiro


下一篇:Shiro