Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧靴CORS过滤器不适用于AngularJS_Java_Angularjs_Spring Boot_Cors_Activiti - Fatal编程技术网

Java 弹簧靴CORS过滤器不适用于AngularJS

Java 弹簧靴CORS过滤器不适用于AngularJS,java,angularjs,spring-boot,cors,activiti,Java,Angularjs,Spring Boot,Cors,Activiti,我创建了一个SpringBoot应用程序,它有一个AngularJS前端,我没有使用任何Spring安全模块 我在控制器中添加了@CrossOrigin注释,如下所示 @CrossOrigin(origins = "http://localhost:3000", maxAge = 3600) @RestController public class MyController { public static final Logger logger = LoggerFactory.getLog

我创建了一个SpringBoot应用程序,它有一个AngularJS前端,我没有使用任何Spring安全模块

我在控制器中添加了@CrossOrigin注释,如下所示

@CrossOrigin(origins = "http://localhost:3000", maxAge = 3600)
@RestController
public class MyController {
   public static final Logger logger = LoggerFactory.getLogger(MyController.class);
   .....
   .....
我还创建了一个CORS过滤器,如下所示

@Component
public class CORSFilter implements Filter {

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    chain.doFilter(req, res);
}

public void init(FilterConfig filterConfig) {}
public void destroy() {}
}

我的angularJS前端中的选项出现以下错误

XMLHttpRequest cannot load http://localhost:8080/abc/books/. Response for preflight has invalid HTTP status code 401 (edited)

[12:10] 
zone.js:2744 OPTIONS http://localhost:8080/abc/books/ 401 ()
我的SpringBoot应用程序与PostMan配合得很好,在我使用Chrome时会发生飞行前错误。我怎样才能修好它

编辑 我还使用activiti spring boot starter rest api,该api具有以下功能:

import org.activiti.engine.IdentityService;
import org.activiti.engine.identity.User;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class AuthenticationService {

@Bean
InitializingBean usersAndGroupsInitializer(final IdentityService identityService) {

    return new InitializingBean() {
        public void afterPropertiesSet() throws Exception {
            User admin = identityService.newUser("admin");
            admin.setPassword("admin");
            identityService.saveUser(admin);
            }
        };
    }

}

这是一个Spring CORS过滤器,可与AngularJS配合使用

public class CORSFilter extends OncePerRequestFilter {

    private final Logger LOG = LoggerFactory.getLogger(CORSFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException {
        LOG.info("Adding CORS Headers ........................");        
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
        res.addHeader("Access-Control-Expose-Headers", "xsrf-token");
        if ("OPTIONS".equals(req.getMethod())) {
            res.setStatus(HttpServletResponse.SC_OK);
        } else { 
            chain.doFilter(req, res);
        }        
    }

我从帖子中发现了这一点,正如评论中提到的,问题在于
activitispringbootstarterrestapi
附带了开箱即用的安全性。这里的问题是,它们在根上下文上应用了安全性,这意味着任何其他端点也将具有身份验证

选项1:添加您自己的安全性 要解决此问题,您可以创建自己的具有更高优先级的
SecurityConfig
类,并允许所有请求转到
/abc/**
(或任何其他内容),例如:

@Order(Ordered.HIGHEST_PRECEDENCE) // This should "overrule" Activiti's security
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/abc/**")
            .authorizeRequests().anyRequest().permitAll();
    }
}
@Component
@Order(1) // You can choose the value yourself
public class CORSFilter implements Filter {
    // ...
}

选项2:禁用Activiti的安全性 或者,您可以禁用Activiti的安全自动配置:

@EnableAutoConfiguration(exclude = {
    org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class,
    org.activiti.spring.boot.SecurityAutoConfiguration.class
})
这将禁用Activiti和Spring引导本身的安全自动配置。如果您只禁用Activiti的安全配置,Spring boot的自动配置就会启动,并且您仍然可以在所有端点上进行身份验证

然而,您可能仍然希望在Activiti的一些端点上应用安全性,但这允许您自己定制它,而不是依赖于自动配置。在您的情况下,您可以选择对Activiti正在使用的所有
/identity/**
/management/**
/history/**
/repository/**
/query/**
/runtime/**
路径应用安全性


选项3:在出现
选项时覆盖过滤器链
第三种选择是绕过整个安全过滤器链。如中所示,您可以通过不调用
chain.doFilter(req,res)
来打破过滤器链。这可以通过在过滤器中添加以下内容来实现:

if (HttpMethod.OPTIONS.name().equalsIgnoreCase(req.getMethod()) {
    res.setStatus(HttpServletResponse.SC_OK);
} else {
    chain.doFilter(req, res); // Only apply doFilter() when not OPTIONS
}
注意:请注意,这只允许调用
选项。安全性还影响您在控制器中定义的其他端点,而不仅仅是
选项
调用

通过有条件地调用
doFilter()
,您可以跳过整个安全筛选器链,以防出现
OPTIONS
请求。您必须将
req
res
分别转换为
HttpServletRequest
HttpServletResponse

此外,您必须确保在安全筛选器链之前调用此筛选器。为此,请将
CORSFilter
的顺序更改为选定的值,例如:

@Order(Ordered.HIGHEST_PRECEDENCE) // This should "overrule" Activiti's security
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/abc/**")
            .authorizeRequests().anyRequest().permitAll();
    }
}
@Component
@Order(1) // You can choose the value yourself
public class CORSFilter implements Filter {
    // ...
}
现在,通过将
application.properties
中的
security.filter order
属性设置为更高的值来更改安全过滤器链顺序:

security.filter-order=2

@g00glen00b我没有spring安全性enabled@g00glen00b这是有道理的。我已经编辑了我的问题。我没有意识到activiti的依赖性可能是问题的根源。有没有一种方法可以禁用对选项的授权要求?据我所知,只有在安全筛选器链之前订购筛选器时,这才有效。我尝试了选项1。但它给了我同样的错误。我在我的应用程序上启用了调试模式,这就是我看到的。名为“DispatcherServlet”的DispatcherServlet正在处理[/books/error]的选项请求。当您尝试使用PostMant时,它如何返回正确的url端点是
/books/error
,我想它不属于
/abc/**
匹配器?所以这可能就是问题所在。我暂时选择了选项2。如果我想为某些URL启用它,我必须为这些端点创建单独的安全配置吗?如果它们没有类似的路径,可能是的。在这些情况下,最好选择选项2并定义自己的
SecurityConfig
保护Activiti本身的路径。