如何从 angular localhost:4200 调用 spring security azure AD localhost:8080。天蓝色调用中的错误

Posted

技术标签:

【中文标题】如何从 angular localhost:4200 调用 spring security azure AD localhost:8080。天蓝色调用中的错误【英文标题】:How to call spring security azure AD localhost:8080 from angular localhost:4200. Error in azure call 【发布时间】:2020-10-11 12:22:52 【问题描述】:

包 com.example.demo;

import java.util.Arrays;
import java.util.Collections;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

private final OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;

public SecurityConfiguration(OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService) 
    System.out.println("loading user:" + oidcUserService);
    this.oidcUserService = oidcUserService;


@Override
protected void configure(HttpSecurity http) throws Exception 
    http.cors()
    .and().authorizeRequests()
    .anyRequest()
    .authenticated()
    .and()
    .oauth2Login()
    .userInfoEndpoint().oidcUserService(oidcUserService);


 @Bean
    CorsConfigurationSource corsConfigurationSource() 
    
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("*"));
    configuration.setAllowedHeaders(Arrays.asList("*"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
    

API:

    package com.example.demo;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class AccountResource 
    
        @Autowired
        AdUserInfo adUserInfo;
    
        @CrossOrigin(origins = "http://localhost:4200")
        @GetMapping("/account")
        public AdInfo getAccount() 
            adUserInfo.setEmail("abc@gmail.com");
            return new AdInfo();
        
    

角度代码:

        import  Injectable  from '@angular/core';
        import  HttpClient  from '@angular/common/http';
        import  Observable, Subject  from 'rxjs';
        import  AdInfo  from './ad-info';
        @Injectable(
          providedIn: 'root'
        )
        export class LoginService 
          private loginUrl: string;
          constructor(private http: HttpClient) 
            this.loginUrl = 'http://localhost:8080/account';
          
        
          public login(): Observable<AdInfo> 
            return this.http.get<AdInfo>(this.loginUrl);
          
        
        

角度类:

            export class AdInfo 
                id: string;
                name: string;
                email: string;
            

从 http://localhost:8080 调用工作正常。它转到 azure 和 login 。根据 • https://docs.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory。

现在我想从 Angular UI 调用它。所以本地主机:4200。做了一个登录页面。 Onlick 登录按钮。它正在调用 localhost:8080。但显示重定向到 azure 广告登录时出错。

错误: 在 'https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id=******&scope=openid%20https://graph.microsoft.com/user.read&state=a04QyhpKFkvGUvjUCRwZ834QhTgzTFYIu74M0768Co0 访问 XMLHttpRequest %3D&redirect_uri=http://localhost:8080/login/oauth2/code/azure'(从 'http://localhost:8080/account' 重定向)来自 'http://localhost:4200' 已被 CORS 阻止策略:请求的资源上不存在“Access-Control-Allow-Origin”标头

在 'https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id=******&scope=openid%20https://graph.microsoft.com/user 访问 XMLHttpRequest。 read&state=Du8JvHSEGdD3xcBft6B683mDrW8Zedppel1Xz6lBZwY%3D&redirect_uri=http://localhost:4200/login/oauth2/code/azure'(重定向自'http://localhost:4200/account')来自原点'http://localhost:4200'被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。

【问题讨论】:

任何人都知道如何从角度调用 localhost:8080(docs.microsoft.com/en-us/azure/developer/java/spring-framework/…)。 你不能。这些是 AzureAD 上的不同来源。您可以在您的应用程序中使用重定向/提供 UI 的路由作为解决方法 如何调用 spring azure auth login api((docs.microsoft.com/en-us/azure/developer/java/spring-framework/...) . 从 UI 任何人都知道调用 angular localhost:4200 到 localhost:8080 是 spring azure Ad 。 (弹簧按文档配置:docs.microsoft.com/en-us/azure/developer/java/spring-framework/…))。直接命中 localhosy:8080 工作正常。但是来自4200端口。不工作。有谁知道。请发表评论。紧急 任何人都知道。 java开发者。 SSO 并不新鲜。任何人都已实施。请评论 【参考方案1】:

您可能面临的问题是 Spring Security 不会让飞行前检查请求通过并使其失败。

添加

configuration.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept","Authorization"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));

在 Angular 中尝试添加 Proxying to a backend server

【讨论】:

这个我已经试过了。同样的错误。服务器登录弹出窗口未打开 任何人都有项目或帮助 • docs.microsoft.com/en-us/azure/developer/java/spring-framework/… 来自 Angular 4200。 请参考document和sample 我关注docs.microsoft.com/en-us/azure/developer/java/spring-framework/…。关联。那么是否有任何用户界面。或者代码流

以上是关于如何从 angular localhost:4200 调用 spring security azure AD localhost:8080。天蓝色调用中的错误的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 / Angular 4:如何从本地系统位置访问文件?

如何从 Angular 材质对话框中获取数据?

如何从 Angular 2 中的数据渲染静态 Angular 组件? [复制]

如何从 Angular 7 调用 Web API 返回布尔值?

如何从angular2中的observable获取数据

Angular 如何从 authguard 中检索?