shiro

Subject:用户主体 ,需要SecurityManager

SecurityManager:安全管理器, 需要Realm

Realm:编写认证,授权逻辑

第一步:设置基本的访问规则

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    //设置安全管理器
    shiroFilterFactoryBean.setSecurityManager(securityManager);
    //添加Shiro内置过滤器
    /*
    *   常见的过滤器:
    *       anon:无需认证(登录)可以访问
    *       authc:必须认证才可以访问
    *       user:如果使用rememberMe的功能可以访问
    *       perms:该资源必须得到资源权限才可以访问
    *       role:该资源必须得到角色权限才可以访问
    * */
    Map<String, String> map = new HashMap<>();
    //登出
    map.put("/logout", "logout");
    //对所有用户认证
    map.put("/**", "authc");
    //设置登录
    shiroFilterFactoryBean.setLoginUrl("/login");
    //设置首页
    shiroFilterFactoryBean.setSuccessUrl("/index");
    //设置错误页面,认证不通过跳转
    shiroFilterFactoryBean.setUnauthorizedUrl("/error");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
    return shiroFilterFactoryBean;
}

第二步:拦截通过后,到controller真正执行request请求,校验用户信息

@RequestMapping("/login")
public String login(User user) {
    //添加用户认证信息
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
        user.getUserName(),
        user.getPassword()
    );
    try {
        //进行验证,这里可以捕获异常,然后返回对应信息
        subject.login(usernamePasswordToken);
        //            subject.checkRole("admin");
        //            subject.checkPermissions("query", "add");
    } catch (AuthenticationException e) {
        e.printStackTrace();
        return "账号或密码错误!";
    } catch (AuthorizationException e) {
        e.printStackTrace();
        return "没有权限";
    }
    return "login success";
}

第三步:第二步中,当执行到

//进行验证,这里可以捕获异常,然后返回对应信息
subject.login(usernamePasswordToken);

程序实际来到 CustomRealm 中,执行具体的验证逻辑:

@Override   //认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    //加这一步的目的是在Post请求的时候会先进认证,然后在到请求
    if (authenticationToken.getPrincipal() == null) {
        return null;
    }
    //获取用户信息
    String name = authenticationToken.getPrincipal().toString();
    User user = loginService.getUserByName(name);
    if (user == null) {
        //这里返回后会报出对应异常
        return null;
    } else {
        //这里验证authenticationToken和simpleAuthenticationInfo的信息
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName());
        return simpleAuthenticationInfo;
    }
}

第四步:验证完成后,转到CustomRealm 的授权方法,为人员添加资源授权字符串

@Override   //授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    //获取登录用户名
    String name = (String) principalCollection.getPrimaryPrincipal();
    //查询用户名称
    User user = loginService.getUserByName(name);
    //添加角色和权限
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    for (Role role : user.getRoles()) {
        //添加角色
        simpleAuthorizationInfo.addRole(role.getRoleName());
        //添加权限
        for (Permissions permissions : role.getPermissions()) {
            simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
        }
    }
    return simpleAuthorizationInfo;
}
posted @ 2023-06-14 09:33  谭五月  阅读(34)  评论(0)    收藏  举报