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

查看:54
本文介绍了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:

响应{类型:"cors",网址:"https://login.microsoftonline.com/.../oauth2/token"",重定向:false,状态:400,ok:false,...}身体: (...)bodyUsed:错误标头:标头{}好的:错误重定向: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文件中.例如:\ public \ data \ token.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: \public\data\token.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错误.您将必须允许从用于启动应用程序的本地主机和端口进行调用.您应该选择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天全站免登陆