Springboot整合Shiro不进入doGetAuthorizationInfo方法 没有进行权限认证

新手上路,请多包涵

题目描述

在登录后shiro没有进入Realm的doGetAuthorizationInfo方法,即使调用了subject.isPermitted方法也不行 希望懂shiro的大佬帮我解决一下 十分感谢!!

相关代码

ShiroAuthorizingRealm:

public class ShiroAuthorizingRealm extends AuthorizingRealm {
    @Autowired
    private IUserService userService;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("doGetAuthorizationInfo这里??");
        // 已知用户名
//        String username = principalCollection.getPrimaryPrincipal().toString();

        ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal();
        String username = shiroUser.getUserName();
        //  资源:操作:id     user:create
        List<String> permissionList = this.userService.getUserPermssions(username);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addStringPermissions(permissionList);

        return simpleAuthorizationInfo;
    }

    /**
     * 身份认证信息
     * 重写该方法,从数据库中获取注册用户和对应的密码,封装成AuthenticationInfo对象返回
     * */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // authenticationToken 当前登录用户的身份标识
        // 已知用户名
        System.out.println("身份认证信息doGetAuthenticationInfo这里??");
        String username = authenticationToken.getPrincipal().toString();
        // 再根据用户名从数据库中找密码
        AuthSysUser user = this.userService.findByUserName(username);
        if(user == null){
            throw new AccountException("account not exist");
        }
        String password = user.getUrPassword();
        // 用AuthenticationInfo对象,封装username和password
        ShiroUser shiroUser = new ShiroUser();
        shiroUser.setId(user.getUrId());
        shiroUser.setUserName(user.getUrUserName());
        shiroUser.setPassword(password);
        shiroUser.setAuthCacheKey(user.getUrUserName()+user.getUrId());
        SimpleAuthenticationInfo info= new SimpleAuthenticationInfo(shiroUser, password, this.getName());
        return info;
    }
}

PermissionAuthFilter:权限过滤器

public class PermissionAuthFilter extends AccessControlFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        boolean bool = true;
        // 拼凑当前请求url对应的权限字符串   /user/create?xxxxx
        HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
        String requestURI = httpRequest.getRequestURI();

        String[] permStrs = requestURI.split("/");
        if(permStrs != null && permStrs.length>2) {
            String perm = permStrs[1]+":"+permStrs[2];
            // 资源名称:操作:对象id
            // user:create,update,delete,search,other:*
            // shop:create,update,delete...:*
            // who what how
            // 获取当前用户对应的subject对象
            Subject subject = this.getSubject(servletRequest,servletResponse);
            //Object primary = subject.getPrincipals().getPrimaryPrincipal();
            // 调用subject对象的方法,判断是否有权限
            // 返回判断结果
            bool = subject.isPermitted(perm);
//            bool = subject.hasRole(perm);
            System.out.println(subject.hasRole(perm));
        }
        bool = true;
        return bool;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        ((HttpServletRequest)servletRequest).getRequestDispatcher("/auth/noAuth").forward(servletRequest,servletResponse);
        return false;
    }
}

ShiroConfiguration类:

@Configuration
@Slf4j
public class ShiroConfiguration {
    @Autowired
    private RedisUtil redisUtil;

    private TokenAuthFilter tokenAuthFilter;

    private PermissionAuthFilter permissionAuthFilter;
    @Autowired
    private IPermissionService permissionService;

    private static final String CACHE_KEY = "shiro:cache:";
    private static final String SESSION_KEY = "shiro:session:";
    private static final String NAME = "custom.name";
    private static final String VALUE = "/";

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 创建一个Map对象包含所有要集成到Shiro框架中去的filter对象
        // 注册哪些过滤器
        Map<String, Filter> filters = new HashMap<String, Filter>();
        // <filter>
        // <filter-mapping
        this.tokenAuthFilter = new TokenAuthFilter();
        this.tokenAuthFilter.setRedisUtil(this.redisUtil);
        this.permissionAuthFilter = new PermissionAuthFilter();

        filters.put("authcToken", this.tokenAuthFilter);
        filters.put("permAuthc", this.permissionAuthFilter);

        // 在shiro中注册过滤器
        shiroFilterFactoryBean.setFilters(filters);

        // 设置哪些过滤器拦截哪些请求
        Map<String,String> permChainMap = new HashMap<>();
        //permChainMap.put("/user/**", "tokenAuthc");
        List<AuthSysPermission> permissionList = this.permissionService.searchPermissions();
        if(permissionList != null){
            for(AuthSysPermission permission:permissionList){// /user/**
                permChainMap.put("/"+permission.getResources().getRscUrl()+"/**", "authcToken, permAuthc");
            }
        }

        shiroFilterFactoryBean.setFilterChainDefinitionMap(permChainMap);

        // 其它的设置
        shiroFilterFactoryBean.setLoginUrl("/auth/login");
        //shiroFilterFactoryBean.setSuccessUrl();
        shiroFilterFactoryBean.setUnauthorizedUrl("/auth/noAuth");

        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }

    @Bean("securityManager") // 固定!
    public DefaultWebSecurityManager createSecurityManager(@Qualifier("shiroRealm") ShiroAuthorizingRealm shiroRealm){
        System.out.println("createSecurityManager这里?");
        // 创建SecurityMananger对象,并且装配Realm对象
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager(shiroRealm);
        // 自定义缓存实现 使用redis
        manager.setCacheManager(cacheManager());
        // 自定义session管理 使用redis
        manager.setSessionManager(sessionManager());
        /*
         * 关闭shiro自带的session,详情见文档
         * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
         */
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        manager.setSubjectDAO(subjectDAO);
        manager.setRealm(shiroRealm);

        return manager;
    }

    /**
     * Session Manager
     * 使用的是shiro-redis开源插件
     */
    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionDAO(redisSessionDAO());
        // 允许支持基于Cookie传递的会话id
        sessionManager.setSessionIdCookieEnabled(true);
        // 支持请求的url重新(通过url传递会话id)
        sessionManager.setSessionIdUrlRewritingEnabled(true);

        SimpleCookie simpleCookie = new SimpleCookie();
        simpleCookie.setName(NAME);
        simpleCookie.setValue(VALUE);
        // 设置传递会话id的cookie的属性
        sessionManager.setSessionIdCookie(simpleCookie);

        return sessionManager;
    }

    // 准备RedisSessionDAO
    /**
     * RedisSessionDAO shiro sessionDao层的实现 通过redis
     * 使用的是shiro-redis开源插件
     */
    @Bean
    public RedisSessionDAO redisSessionDAO() {
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());
        redisSessionDAO.setExpire(86400);
        redisSessionDAO.setKeyPrefix(SESSION_KEY);
        return redisSessionDAO;
    }
    /**
     * cacheManager 缓存 redis实现
     * 使用的是shiro-redis开源插件
     *
     * @return
     */
    public RedisCacheManager cacheManager() {
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        // 装配redisManager
        redisCacheManager.setRedisManager(redisManager());
        redisCacheManager.setExpire(86400);
        redisCacheManager.setKeyPrefix(CACHE_KEY);
        return redisCacheManager;
    }
    /**
     * 配置shiro redisManager
     * 使用的是shiro-redis开源插件
     *
     * @return
     */
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();
        redisManager.setHost("127.0.0.1");
        redisManager.setPort(6379);
        redisManager.setTimeout(0);
        // redisManager.setPassword(password);
        return redisManager;
    }
}
阅读 1.5k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题