我可以对AD进行身份验证,但后来我想对在AD中注册的API / APP进行后续调用.
我试过用这个例子:
public CallAPI() { let headers = new Headers({ 'Content-Type': 'application/json' }); var token; this.service.acquireToken("{client id}").subscribe(p => { token = p; headers.append("Authorization",'Bearer ' + token); let options = new RequestOptions({ headers: headers }); // Make the HTTP request: this.httpClient.get('https://localhost:45678/stuff',options).subscribe(data => { // Read the result field from the JSON response. this.results = data['results']; console.log(data); }); },(error => { console.log(error); })); }
我遇到的第一个问题是CORS错误.我在localhost上运行客户端应用程序:并获取:
XMLHttpRequest cannot load 07001. Redirect from ‘07001’ to ‘07003……….’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘07004’ is therefore not allowed access.
我尝试访问的app / API也在本地运行(客户端和服务器都是https)
它们都是活动目录中的已注册应用程序,其登录/应用程序ID uris设置为各自的本地主机地址.
app / api使用服务堆栈,因此设置:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); app.UseWindowsAzureActiveDirectoryBearerAuthentication( new WindowsAzureActiveDirectoryBearerAuthenticationOptions { TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters { ValidAudience = Audience },Tenant = Domain }); public override void Configure(Container container) { AddPreRequestFilters(); AddErrorResponseFilters(); this.Plugins.AddRange(ServiceConfiguration.GetPlugins()); this.Plugins.Add(new SwaggerFeature()); this.Plugins.Add(new CorsFeature(allowedHeaders: "Origin,X-Requested-With,Content-Type,Accept,Authorization",allowCredentials: true)); ServiceConfiguration.Configure(container); }
为了绕过CORS错误,我使用了Allow-Control-Allow-Origin chrome扩展,使用这个我得到一个OPTIONS请求,然后是302(到我的’stuff’端点),它包含我的授权:Bearer {token}标题.最后有一个OPTIONS和GET(带有auth标题)来登录.microsoft.com /…./ oath2 …
这总是无法登录.
我的ADAL配置如下所示:
const config: adal.Config = { tenant: 'xxxx.onmicrosoft.com',clientId: 'xxxxxxxxxxxxxx',// client id of AD app redirectUri: 'https://localhost:4200/',// the angular app cacheLocation: 'localStorage' }
我有什么明显的遗失吗?我也尝试使用endpoints属性绕过acquireToken步骤无济于事:
endpoints: { 'https://localhost:45678/': 'https://localhost:45678/' <-- the address of the API/APP I want to call }
解决方法
首先在handleWindowCallback中,在我们的情况下,requestType始终设置为UNKNOWN,因此statematch始终为false.
这里有点黑客攻击:
if(requestInfo.requestType === 'UNKNOWN') { requestInfo.requestType = this.adalContext.REQUEST_TYPE.RENEW_TOKEN; requestInfo.stateMatch = true; }
我们还必须改变这个:
else if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.RENEW_TOKEN) { this.adalContext.callback = window.parent.callBackMappedToRenewStates[requestInfo.stateResponse]; }
对此:
else if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.RENEW_TOKEN) { this.adalContext.callback = window.parent.callBackMappedToRenewStates[ decodeURIComponent(requestInfo.stateResponse)]; }
stateResponse中的url被编码(百分比符号等),因此永远不会匹配,使回调为null.
希望这有助于某人 – 也许找到更好的解决方案!
这是叉子:adal-angular4