首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AngularJS SpringSecurity CORS问题

AngularJS SpringSecurity CORS问题
EN

Stack Overflow用户
提问于 2016-10-15 00:28:12
回答 1查看 174关注 0票数 0

我正在设置一个Angular+Spring安全模块来登录和注册用户。当我注册一个用户时,一切都很好。注册后的最后一步是自动登录,但我遇到了以下错误:

XMLHttpRequest无法加载http//localhost:8080/com/登录。请求的资源上没有“访问-控制-允许-原产地”标题。因此,原产地'http//localhost:9000‘是不允许访问的。响应具有HTTP状态代码401。

安古拉杰的辅助服务:

代码语言:javascript
复制
.factory("sessionAccountService", function($http){
        var session = {};
        session.login = function(data){
            return $http.post("http://localhost:8080/com-tesis/login",
                              "username="+data.name+"&password="+data.password,
                              {headers: {"Access-Control-Allow-Headers":"Content-Type"}}
            ).then(function(data){
                alert("loggin correcto");
                localStorage.setItem("session",{});
            }, function(data){
                alert("error login in");
            });

        };
        session.logout = function(){
            localStorage.removeItem("session");
        };
        session.isLoggedIn = function(){
            return localStorage.getItem("session") !== null;
        }
        return session;
    })
  .factory("accountService", function($resource){
        var service = {};
        service.register = function(account, success, failure){
            var Account = $resource("http://localhost:8080/com-tesis/rest/accounts");
            Account.save({},account,success,failure);
        };
        service.userExists = function(account, success, failure){
            var Account = $resource("http://localhost:8080/com-tesis/rest/accounts");
            var data = Account.get({name:account.name}, function(){
                var accounts = data.accounts;
                if (accounts.length !== 0){
                    success(accounts[0]);
                } else {
                    failure();
                }
            }, 
            failure);
        }
        return service;
    });

这是在后端端实现的CORS过滤器:

代码语言:javascript
复制
package tesis.core.security;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class SimpleCORSFilter implements Filter {

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

    public SimpleCORSFilter() {
        log.info("SimpleCORSFilter init");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");

        if (request.getMethod().equals("OPTIONS")) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

}

这是web.xml上的过滤器

代码语言:javascript
复制
<filter>
        <filter-name>simpleCORSFilter</filter-name>
        <filter-class>
            tesis.core.security.SimpleCORSFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>simpleCORSFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

我很困惑,这是Chrome的请求:req/res

我不知道我做错了什么。谢谢!

编辑:当我从同一个url http//localhost:8080/发送请求时,效果很好。从http//localhost:9000 spring始终返回SC_UNAUTHORIZED

这是SecurityConfig

代码语言:javascript
复制
package tesis.core.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private AuthFailure authFailure;

    @Autowired
    private AuthSuccess authSuccess;

    @Autowired
    private EntryPointUnauthorizedHandler unauthorizedHandler;

    @Autowired 
    private UserDetailServiceImpl userDetailService;

    @Autowired
    public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception{
        builder.userDetailsService(userDetailService);
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .and()
            .formLogin()
                .successHandler(authSuccess)
                .failureHandler(authFailure)
            .and()
            .authorizeRequests()
                .antMatchers("/**")
                .permitAll();
    }
}

AuthSuccess和AuthFailure类

代码语言:javascript
复制
package tesis.core.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

@Component
public class AuthSuccess extends SimpleUrlAuthenticationSuccessHandler{

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {

        response.setStatus(HttpServletResponse.SC_OK);
    }

}

package tesis.core.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

@Component
public class AuthFailure extends SimpleUrlAuthenticationFailureHandler{

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {

        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-19 02:40:20

最后我找到了解决办法。首先,为了解决401错误,我重新编写了如下请求:401溶液

在此之后,出现了一个新错误:

在请求的资源上没有“访问-控制-允许-原产地”标头,因此不允许访问。

然后,阅读Spring,我意识到我必须明确地说要使用哪个头。这条线索:Spring :报头-静态

因此,这是固定的SecurityConfig文件:

代码语言:javascript
复制
package tesis.core.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.header.writers.StaticHeadersWriter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private AuthFailure authFailure;

    @Autowired
    private AuthSuccess authSuccess;

    @Autowired
    private EntryPointUnauthorizedHandler unauthorizedHandler;

    @Autowired 
    private UserDetailServiceImpl userDetailService;

    @Autowired
    public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception{
        builder.userDetailsService(userDetailService);
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return new SimpleUrlAuthenticationFailureHandler();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .headers().addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Origin","*"))
            .and()
            .exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .and()
            .formLogin()
                .successHandler(authSuccess)
                .failureHandler(authFailure)
            .and()
            .authorizeRequests()
                .antMatchers("/**")
                .permitAll();
    }
}

感谢每个人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40053767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档