REACT 应用程序调用安全的 Azure WEBAPI 服务 - 没有用户 [英] REACT application to call secure Azure WEBAPI Service - NO USERS

查看:14
本文介绍了REACT 应用程序调用安全的 Azure WEBAPI 服务 - 没有用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个简单的 REACT 应用程序,它只能在连接到我们网络上的大屏幕的本地 PC 上运行.限内部使用!它就像一个广告牌或仪表板.用户交互为零.屏幕不是触摸屏,也没有连接键盘和鼠标.因此没有用户可以登录.

I have created a simple REACT application that is ONLY run on a local PC attached to a large screen on our network. Internal use only! It is like a billboard or dashboard. There is ZERO user interaction. The screen is NOT a touch screen and there is no keyboard and mouse attached. Therefore NO users to login.

REACT 应用程序已构建,然后部署到 PC 上的文件夹中.全部自动化.初始部署包括所有当前数据.然后在 Windows 启动时执行类似这样的命令:python -m http.server 3000"(只是示例...)

The REACT application is build and then deployed to a folder on the PC. All automated. The initial deployment includes all current data. Then at windows startup a command something like this is executed: "python -m http.server 3000" (just example...)

应用程序具有随应用程序一起部署的初始数据,但是,我希望它也能够调用安全的 Azure WebAPI 服务以每隔几分钟获取更新的统计信息.非常小的数据.主要是整数值.我只是想提供一些实时更新.

The application has initial data that was deployed with the application, however, I would like it to also be able to call a secure Azure WebAPI service to get updated statistics every few minutes. Very small data. Mostly integer values. I just want to provide some real time updates.

我的 REACT 应用程序可以正常工作(如果 WEBAPI 不安全)或个别调用允许匿名.但是,我们的业务规则要求所有端点都是安全的.

I have the REACT app fully working (if the WEBAPI is not secure) or the individual calls allow anonymous. However, we have business rules that require all endpoints to be secure.

此应用在本地运行,但 API 是 Azure 应用服务.

This app runs locally, but the API is an Azure App Service.

我已将 Azure AD 中的 REACT 应用程序设置为注册应用程序,并将其配置为有权调用 WEBAPI 服务.

I have setup the REACT application in Azure AD as a registered application and configured it to have permissions to call the WEBAPI service.

我有许多控制台应用程序,它们的设置和工作方式与这个 REACT 应用程序基本相同.对于 C# 守护程序应用程序,有一个 MSAL 包可以轻松完成.

I have many console applications that are setup and work basically the same way as this REACT application. With the C# daemon applications, there is a MSAL package that makes it easy.

我正在尝试学习 REACT,而不是将其构建为另一个 WPF 或 UWP 应用程序,我想尝试使用 REACT.

I am trying to learn REACT, and instead of building this as another WPF or UWP application, I wanted to try using REACT.

所以,我知道我需要一个访问令牌.我正在考虑客户端 ID 和 Secret,就像我在用 C# 编写的 C# 守护程序客户端中所做的那样.

So, I know I need an access token somehow. I was thinking with a client ID and Secret just like I do in my C# daemon clients that are written in C#.

我找不到任何在没有用户登录的情况下执行此操作的 REACT 或 Angular 示例.请记住,PC 没有输入设备.仅显示.同样,我的应用没有用户.它调用安全 API 来获取数据.就是这样.

I cannot find any REACT nor Angular examples that do this without a user login first. Remember, the PC does not have input devices. Display ONLY. Again, my app does not have users. It calls a secure API to get data. That's it.

感谢您的帮助.

使用 Joy Wang 的评论和文档中的此页面:服务到服务访问令牌请求

Using Joy Wang's comments and this page from documentation: Service-to-Service Access Token Request

这是我的新代码:

const adalConfig = {
  tenant: '...',
  clientId: '...',
  clientSecret: '...',
  authority: 'https://login.microsoftonline.com/{tenant}/oauth2/token',
  endpoints: {
    apiResourceId: 'api://bbbbbb-...',
  },
};

function getAccessToken() {
  var requestParams = {
    grant_type: 'client_credentials',
    client_id: adalConfig.clientId,
    client_secret: adalConfig.clientSecret,
    resource: adalConfig.endpoints.apiResourceId
  };

  // Make a request to the token issuing endpoint.
  fetch(adalConfig.authority,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify( requestParams )
    }).then(response => {
      if (response.status >= 200 && response.status < 300) {
        console.log(response);
        console.log(response.json());
      } else {
        console.log('Somthing happened wrong');
        console.log(response);
      }
    }).catch(err => err);
}

当我调用上面的函数时,我得到以下响应:

When I call the function above, I get the following response:

响应 {type: "cors", url: "https://login.microsoftonline.com/.../oauth2/token", 重定向: false, status: 400, ok: false, …}身体: (...)身体使用:假标头:标头{}好的:假的重定向:假状态:400statusText:错误请求";类型:cors";网址:https://login.microsoftonline.com/.../oauth2/token"原型:响应

Response {type: "cors", url: "https://login.microsoftonline.com/.../oauth2/token", redirected: false, status: 400, ok: false, …} body: (...) bodyUsed: false headers: Headers {} ok: false redirected: false status: 400 statusText: "Bad Request" type: "cors" url: "https://login.microsoftonline.com/.../oauth2/token" proto: Response

也许还有另一种方法可以启动 REACT 应用程序,以便不检查 CORS?有什么想法吗?

Maybe there is another way to start the REACT application so that CORS is not checked? Any ideas?

再次感谢.

推荐答案

所以,目前没有一种安全的方式来做我想做的事.基本问题是您不能在浏览器中使用来自 JavaScript 的客户端凭据授予类型.

So, currently there is not a secure way to do what I want. The basic issue is that you cannot use the client credential grant type from JavaScript in a browser.

但是,我认为我有一个很好的解决方法可以帮助其他人.我确信它不适用于大多数应用程序.而且我相信 OAUTH 正在研究解决方案,因此在不久的将来可能不需要.如果添加了更好的解决方案,我很乐意将其标记为正确答案.感谢您的帮助.

However, I think I have a good work around that may help others. I am sure it is NOT for most application. And I believe OAUTH is working on a solution so this may not be needed in the near future. If a better solution is add, I will gladly mark it as the correct answer. Thanks for your help.

我的应用基本上是一个用户输入为零的自动化仪表板/广告牌.它提取安全数据并显示它.REACT 应用程序仅在没有输入的墙壁上的本地 PC 上.开启 PC 时运行脚本.

My app is basically an automated dashboard/billboard with ZERO user input. It pulls secure data and displays it. The REACT application is ONLY on a LOCAL PC on a wall with NO inputs. A script runs when the PC is turned on.

脚本使用 python 之类的 http 服务器启动构建的 REACT 应用程序.例如:python -m http.server 8000"

The script starts the built REACT application using an http server like python. Ex: "python -m http.server 8000"

该脚本随后以信息亭模式打开浏览器,因此您在屏幕上看到的唯一内容就是应用程序.

The script then opens the browser in kiosk mode so the only thing you see on the screen is the application.

到目前为止,这和我之前的完全一样.

So far, this is exactly as I had it before.

解决方法:我创建了一个名为 GetToken 的命令行实用程序.在脚本启动 REACT 应用程序之前,它会像这样调用此实用程序:gettoken --client Dashboard --file token.json"此实用程序调用客户端凭据授予类型以获取令牌.然后它将该令牌与其他构建的 REACT 文件一起保存到本地 json 文件中.例如:publicdata oken.json

WORK AROUND: I created a command line utility called GetToken. Before the REACT application is started by the script, it calls this utility like so: "gettoken --client Dashboard --file token.json" This utility makes the Client Credential Grant Type call to get a token. It then saved that token to a local json file with the other built REACT files. Ex: publicdata oken.json

在我的 REACT 应用程序中,它只是加载令牌并使用它.

In my REACT application, it just loads the token and uses it.

const t = await fetch('./data/token.json').then(r => r.json());
this.setState({ token: t.token });

然后我将其添加到我的 api 调用中,如下所示:

Then I just add this to my api calls like so:

const fetchOptions = {
  method: 'GET',
  headers: {
    "Authorization": `Bearer ${this.state.token}`,
    "Content-Type": "application/json"
  }
};
const newSlides = await fetch(this.state.baseUrl + '/api/Dashboard/GetSlides', fetchOptions).then(response => response.json());

重要提示:这仅适用于您还能够更新 API 的情况.如果你不能,那么你仍然会得到 CORS 错误.您必须允许来自用于启动应用程序的 localhost 和端口的调用.您应该选择 3000、4200 或 8000 以外的值.

IMPORTANT: This only works if you also have the ability to update the API. If you cannot, then you will still get CORS errors. You will have to allow calls from the localhost and port you use to start you application. You should pick something other than 3000, 4200, or 8000.

我在我的 API startup.cs 中添加了以下内容:

I added the following to my API startup.cs:

public void ConfigureServices(IServiceCollection services) {
  ...

  var origins = Configuration.GetSection("AppSettings:AllowedOrigins").Value.Split(",");
  services.AddCors(o => o.AddPolicy(specificOriginsPolicy, builder => {
    builder.WithOrigins(origins)
      .AllowAnyMethod()
      .AllowAnyHeader()
      .AllowCredentials()
      .SetIsOriginAllowed((host) => true);
  }));

  ...
}

public void Configure(IApplicationBuilder app) {
  ...
  app.UseCors(specificOriginsPolicy);
  ...
}

我仍在完善此解决方案,但到目前为止效果很好.我可以将该实用程序变成一个后台服务,它会定期更新令牌.或者我可以将实用程序转换为 Shell,然后使用它而不是脚本.不管怎样,你明白了.

I am still refining this solution, but it works well so far. I may turn the utility into a background service that is updating the token on an interval. Or I may turn the utility into a Shell, and then use it instead of the script. Either way, you get the idea.

课程:我知道我可以将其作为 UWP 或 WPF 应用程序来完成并避免所有这些问题,但主要目标是学习 REACT.我学到了很多.我会再做一次.令人震惊的是,我的 REACT 应用程序现在已经完成了这么少的代码.我相信 REACT 可以用于许多类似的场景.

LESSON: I know I could have done this as a UWP or WPF application and avoided all these issues, but the main goal was to learn REACT. I learned a lot. I would do it again. It is shocking just how little code there is to my REACT application now that it is done. I believe REACT could be used for many similar scenarios.

这篇关于REACT 应用程序调用安全的 Azure WEBAPI 服务 - 没有用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆