带有oauth2 sso和angular 2 CORS问题的spring zuul网关

Posted

技术标签:

【中文标题】带有oauth2 sso和angular 2 CORS问题的spring zuul网关【英文标题】:spring zuul gateway with oauth2 sso and angular 2 CORS issue 【发布时间】:2017-06-16 17:55:54 【问题描述】:

您好,我的微服务 sso 设置存在 CORS 问题,但我无法弄清楚原因。我的设置:

oauth 微服务端口 8899:

@Configuration
@Order(-20)
public class EndpointSecurityConfig extends WebSecurityConfigurerAdapter 

private AuthenticationManager authenticationManager;

@Autowired
public EndpointSecurityConfig(AuthenticationManager authenticationManager) 
   this.authenticationManager = authenticationManager;


@Override
public void configure(HttpSecurity http) throws Exception 
// @formatter:off

  http
    .formLogin()
      .loginPage("/login")
      .usernameParameter("name")
      .loginProcessingUrl("/login.do").permitAll()
    .and()
      .requestMatchers().antMatchers("/login", "/login.do", "/oauth/authorize", "/oauth/confirm_access")
    .and()
      .authorizeRequests().anyRequest().authenticated();

// @formatter:on


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
  auth.parentAuthenticationManager(authenticationManager);


PrincipalRestController

@RestController
public class PrincipalRestController 

@RequestMapping("/principal")
Principal principal(Principal principal) 
return principal;
 

zuul网关8765端口:

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableOAuth2Sso
@EnableAutoConfiguration
@EnableFeignClients
public class GatewayApplication extends WebSecurityConfigurerAdapter 

public static void main(String[] args) 
    SpringApplication.run(GatewayApplication.class, args);


@Override
  protected void configure(HttpSecurity http) throws Exception 
    // @formatter:off
    http
        .logout().and()
        .authorizeRequests()
            .antMatchers("/index.html", "/**/*.js", "/", "/login").permitAll()
            .anyRequest().authenticated()
            .and()
        .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    // @formatter:on
  

zuul 配置:

server:
port: 8765

spring:
  aop:
    proxy-target-class: true

security:
  basic:
    enabled: false

oauth2:
  user:
    password: none
  client:
    accessTokenUri: http://localhost:8899/uaa/oauth/token
    userAuthorizationUri: http://localhost:8899/uaa/oauth/authorize
    clientId: client
    clientSecret: secret
  resource:
    userInfoUri: http://localhost:8899/uaa/principal
    preferTokenInfo: false

zuul:
  routes:
    adminPortal:
      url: http://localhost:4200
      path: /**
    user:
      url: http://localhost:8899/uaa/principal

angular 2 应用程序端口 4200 位于网关后面:

服务

@Injectable()
export class LoginService 
 constructor (private http: Http) 

 getLoggedInUser() : Observable<LoggedInUser>

 var authHeader = new Headers();
 authHeader.append( "X-Requested-With", "XMLHttpRequest" );

 return this.http.get("/user",
   headers: authHeader
 )
 .map((res:Response) => res.json())
 .catch((error:any) => Observable.throw(error.json().error || 'Server error'));



logout() : Observable<LoggedInUser>

var authHeader = new Headers();
authHeader.append( "X-Requested-With", "XMLHttpRequest" );

return this.http.post("/logout",,headers: authHeader)
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));



组件

@Component(
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.sass'],
 providers: [ LoginService ]
)
export class AppComponent 

 loggedInUser: LoggedInUser;

 constructor(
   private loginService: LoginService
  )
    this.getLoggedInUser();
  

 getLoggedInUser()
   // Get all comments
   this.loginService.getLoggedInUser()
   .subscribe(
      loggedInUser => this.loggedInUser = loggedInUser,
     err => 
      console.log(err);
    );
   

  logout()
    this.loginService.logout()
   .subscribe(
        loggedInUser => this.loggedInUser = loggedInUser,
        err => 
          console.log(err);
        );
   

  

因此,如果我转到浏览器并打开 localhost:8765/ 请求将植根于执行 getLoggedInUser() 调用的主 angular2 页面。这将转到“localhost:8765/user”,因为在此阶段用户未登录,此调用按预期失败并出现 302,但随后自动重定向到登录也会抛出 302,然后使用 302 执行链中的其他调用。在此同时控制台显示

XMLHttpRequest 无法加载 http://localhost:8899/uaa/oauth/authorize?client_id=client&redirect_uri=http://localhost:8765/login&response_type=code&state=woE3Yc。从“http://localhost:8899/uaa/oauth/authorize?client_id=client&redirect_uri=http://localhost:8765/login&response_type=code&state=woE3Yc”重定向到“http://localhost:8899/uaa/login”已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'http://localhost:8765' 因此不允许访问。

所有这些都在下图中展示:

【问题讨论】:

添加一个允许访问其他站点的标题。 谢谢@RomanC 你可以给我一个这样做的例子吗? 【参考方案1】:

在您的 Spring 应用程序中配置 CORS:https://spring.io/guides/gs/rest-service-cors/

或此文档链接 https://spring.io/blog/2015/06/08/cors-support-in-spring-framework#javaconfig

【讨论】:

是的,我阅读了这篇文章,但没有成功,我在下面添加了代码:@Bean public WebMvcConfigurer corsConfigurer() return new WebMvcConfigurerAdapter() '@Override' public void addCorsMappings(CorsRegistry registry) registry. addMapping("/**").allowedOrigins("localhost:8765"); ; 试试.allowedOrigins("*").allowedOrigins("http://localhost:8765") 是的,对不起,我之前的回答很匆忙,我确实放了“.allowedOrigins('localhost:8765')”,现在我什至尝试了 .allowedOrigins("*") 这个同样的问题:/ 哈哈 github 正在删除 http: ) 您的意思是,您在服务器 localhost:8899 中启用了 CORS,如我所见,您在 8899 和 8765 端口有 2 台服务器 是的,我在 8899 oauth 服务器中添加了 > @Bean public WebMvcConfigurer corsConfigurer() return new WebMvcConfigurerAdapter() '@Override' public void addCorsMappings(CorsRegistry registry) registry.addMapping("/** ").allowedOrigins("localhost:8765"); ;

以上是关于带有oauth2 sso和angular 2 CORS问题的spring zuul网关的主要内容,如果未能解决你的问题,请参考以下文章

使用OAuth2的SSO分析

带有访问/刷新令牌的 Spring Boot OAuth2 SSO 未正确存储在数据库中

使用JWT的OAuth2的SSO分析

带有 Google 的 OAuth2 - CORS 错误(Angular + Spring boot)[重复]

带有 SSO 的 Spring 安全性

如何使用 Angular 2 发送 OAuth2 的客户端 ID 和秘密 ID?