Shiro 集成 No SecurityManager accessible to the calling code....

重写AccessControlFilter的时候一直报下面这个错误,

org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.
    at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123) ~[shiro-core-1.4.0.jar:1.4.0]
    at org.apache.shiro.subject.Subject$Builder.(Subject.java:626) ~[shiro-core-1.4.0.jar:1.4.0]
    at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:56) ~[shiro-core-1.4.0.jar:1.4.0]
    at com.test.shiro.filter.MyAccessControlFilter.onAccessDenied(MyAccessControlFilter.java:70) ~[classes/:na]

代码:

package com.test.shiro.filter;

import com.test.shiro.service.TokenService;
//import com.test.shiro.shiro.MyUsernamePasswordToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Created by pangkunkun on 2017/11/18.
 */
@Component
public class MyAccessControlFilter extends AccessControlFilter {

    private static final Logger log= LoggerFactory.getLogger(MyAccessControlFilter.class);


    /**
     *
     * 如果isAccessAllowed返回true则onAccessDenied方法不会继续执行
     * 这里可以用来判断一些不被通过的链接(个人备注)
     * */
    @Override
    public boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object object) throws Exception{
        return false;
    }

    /**
     * 表示当访问拒绝时是否已经处理了;如果返回true表示需要继续处理;如果返回false表示该拦截器实例已经处理了,将直接返回即可。
     * onAccessDenied是否执行取决于isAccessAllowed的值,如果返回true则onAccessDenied不会执行;如果返回false,执行onAccessDenied
     * 如果onAccessDenied也返回false,则直接返回,不会进入请求的方法(只有isAccessAllowed和onAccessDenied的情况下)
     * */
    @Override
    public boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception{
        System.out.println("onAccessDenied");
        UsernamePasswordToken token1=new UsernamePasswordToken("admin","admin");
        Subject subject= SecurityUtils.getSubject();
        try {
            subject.login(token1);
//            subject.isPermitted("add");
            log.info("subject.hasRole(\"user\");"+subject.hasRole("user"));
        }catch (Exception e){
            log.info("登陆失败");
            log.info(e.getMessage());
            onLoginFail(response);
            return false;
        }
        log.info("登陆成功");
        return true;
    }

    /**
     * 登录失败
     * */
    private void onLoginFail(ServletResponse response) throws IOException {
        log.info("设置返回");
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
//        httpResponse.getWriter().write("login error");
    }

    /**
     * TODO 跨域请求
     */
    private void dealCrossDomain(){

    }
}

查了好多资料感觉都不符合我的问题,后来仔细看异常,有一处This is an invalid application configuration.
这时想到了上面有个@Component注解,这个注解本来想做其它处理的,后来用不到了。将此注解去掉后重新运行OK了。

问题思考,Shiro中的filter是在项目本身的Filter链执行之前加载的,所以感觉这个标签的存在让它没有被正常加载进Shiro的配置中,或者被注册成了Spring的bean,无法被Shiro使用。

你可能感兴趣的:(Shiro)