简体   繁体   English

Angular:只有在授权时才从服务器加载延迟加载的模块(使用 JWT)

[英]Angular: Only load lazy-loaded module from server if authorized (using JWT)

I'm using lazy-loaded modules in my angular application and until now everything works fine.我在我的 angular 应用程序中使用延迟加载模块,直到现在一切正常。

Now I have a specific question about securing and I did not find an answer yet.现在我有一个关于安全的具体问题,但我还没有找到答案。 You have the opportunity to "secure" lazy loaded modules with an Angular Guard and "CanLoad".您有机会使用 Angular Guard 和“CanLoad”来“保护”延迟加载的模块。 But this is only in the frontend and so it could be bypassed and the module would be loaded even if the user is not allowed to see ist.但这只是在前端,因此可以绕过它,即使不允许用户查看 ist,也会加载模块。 Eg Admin-Area.例如管理区域。

I'm using JWTs for authorization and the data is all hosted on an Azure Backend completely separated from the application server that hosts the Angular App.我使用 JWT 进行授权,数据全部托管在 Azure 后端,与托管 Angular 应用程序的应用程序服务器完全分离。

I'm now thinking about if there is any way to use the JWTs to validate and check if the current module is allowed to be loaded by that user server side.我现在在考虑是否有任何方法可以使用 JWT 来验证和检查当前模块是否允许由该用户服务器端加载。

so for example you have the following modules:例如,您有以下模块:

  • FeatureA特征A
  • FeatureB功能B
  • FeatureC功能C
  • Admin行政

In the JWT for every Feature module/area there is a variable in the payload which says if the user is allowed to use this feature (true/false).在每个功能模块/区域的 JWT 中,有效负载中有一个变量,表示是否允许用户使用此功能(真/假)。

Now if the user would try to load the lazy-loaded module for feature A, I would like to validate the JWT on the application server with the public key to know "this key is valid and was signed exactly like that by the azure server".现在,如果用户尝试加载功能 A 的延迟加载模块,我想使用公钥验证应用程序服务器上的 JWT,以了解“此密钥有效并且与 azure 服务器完全一样签名” .

Next it would check if the variable for FeatureA is set to true.接下来,它会检查 FeatureA 的变量是否设置为 true。 If so, I return the module (the js-chunk file) back to the client.如果是这样,我将模块(js-chunk 文件)返回给客户端。 If not, I would return 403 forbidden.如果没有,我会返回 403 forbidden。

so if even the application was modified, the person only gets the feature module if it has an valid JWT which says this feature is activated for that user.因此,即使应用程序被修改,该人也只有在具有有效 JWT 的情况下才能获得该功能模块,该 JWT 表明该功能已为该用户激活。

Is there any way to do this?有没有办法做到这一点? I don't know where I should start looking for a solution.我不知道我应该从哪里开始寻找解决方案。 So if anyone could tell me how I can get that and what I need for it, I would be really grateful!因此,如果有人能告诉我如何获得它以及我需要什么,我将不胜感激!

thanks in advance,提前致谢,

Sazeidya.萨泽迪亚。

... and another developer invents another wheel for another chariot... ......而另一位开发人员为另一辆战车发明了另一个轮子......

First of all, the lazily loaded modules are received by Webpack jsonp function (if we are talking about Angular CLI, which uses Webpack internally) which by default just injects another script into the page;首先,延迟加载的模块由Webpack jsonp 函数接收(如果我们谈论的是内部使用 Webpack 的 Angular CLI),默认情况下它只是将另一个脚本注入页面; that means you have nearly no chance to pass your token with this request because it is loaded as a script, not as XHR.这意味着您几乎没有机会通过此请求传递您的令牌,因为它是作为脚本加载的,而不是 XHR。 Adding token as a get parameter would also be a security issue, so I assume this is also not an option (even if it was achievable).添加令牌作为获取参数也将是一个安全问题,所以我认为这也不是一个选项(即使它是可以实现的)。

Lets assume, that you can change the way how Webpack loads the chunk (or eg write a custom service worker that does what you want, I'm still not sure whether it can be easily done).让我们假设,您可以更改 Webpack 加载块的方式(或者例如编写一个自定义服务工作者来执行您想要的操作,我仍然不确定它是否可以轻松完成)。 Then we come to the question:那么我们来回答这个问题:

Why would you need to protect the admin (or whatever else) module?为什么需要保护管理(或其他)模块?

This is just a piece of code.这只是一段代码。 If you have something sensitive in this module, then it is a problem of your architecture.如果你在这个模块中有一些敏感的东西,那么这是你的架构问题。 All the sensitive data should come from the API.所有敏感数据都应该来自 API。

The only thing you need to protect is the admin API that is used from your application.您唯一需要保护的是在您的应用程序中使用的管理 API。 Every call should be validated against the token that this call provides.每个调用都应根据此调用提供的令牌进行验证。 If the user has the proper scope (or whatever you use for authorization) in the token, then request should return data, otherwise 403. That's pretty much it.如果用户在令牌中具有适当的scope (或您用于授权的任何scope ),则请求应返回数据,否则返回 403。差不多就是这样。

Solution解决方案

It all depends on your backend.这一切都取决于您的后端。

As Angular frontend files are just static files delivered by some server it depends if:由于 Angular 前端文件只是某些服务器提供的静态文件,因此它取决于:

  1. you can differentiate files for modules您可以区分模块的文件
  2. application serving your frontend files can allow/block access to selected files based on some kind of authentication/authorization为您的前端文件提供服务的应用程序可以基于某种身份验证/授权允许/阻止对选定文件的访问

Ad 1广告 1

This is no problem with Angular.这对 Angular 来说没有问题。 You have to build your project with following flag[1]:您必须使用以下标志 [1] 构建您的项目:

ng (...) --named-chunks=true (...)

This will produce modules js files with following names:这将生成具有以下名称的模块 js 文件:

your-module.<hashNumber>.js

Ad 2 - Spring Boot solution广告 2 - Spring Boot 解决方案

In my current project we are using (Java) Spring Boot to serve application frontend and backend.在我当前的项目中,我们使用(Java)Spring Boot 为应用程序前端和后端提供服务。 We are logging into application using spring-security login form.我们正在使用 spring-security 登录表单登录应用程序。 It create session and keeps tracking of this session in cookies.它创建会话并在 cookie 中跟踪此会话。 Cookie is sent to backend on every request - also on loading lazy module. Cookie 会在每次请求时发送到后端 - 也在加载惰性模块时发送。 On the backend side you associate session with user role.在后端,您将会话与用户角色相关联。 This let you allow user to download Angular modules based on user being logged in and having proper role.这使您可以允许用户根据登录的用户和具有适当角色的用户下载 Angular 模块。

<security:intercept-url pattern="/your-module.*.js" access="hasAnyRole('SOME_ROLE')"/> <security:intercept-url pattern="/your-module.*.js" access="hasAnyRole('SOME_ROLE')"/>

Ad 2 - cloud (AWS)广告 2 - 云 (AWS)

As I'm not familiar with Azure but I have some background with AWS I may try describe some AWS based solution which should be possible to port to all major cloud providers.由于我不熟悉 Azure 但我有一些 AWS 背景,我可能会尝试描述一些基于 AWS 的解决方案,这些解决方案应该可以移植到所有主要的云提供商。

If you are using cloud provider authentication and authorization system (like AWS Cognito) then you should be able to protect access to your:如果您使用云提供商身份验证和授权系统(如 AWS Cognito),那么您应该能够保护对您的访问:

a) storage (like S3) or a) 存储(如 S3)或

b) application served on VM (like EC2). b) 在 VM(如 EC2)上提供服务的应用程序。

In first condition (a) you may be able to setup policies to access selected modules (JavaScript files) based on some kind of policies (resource access restrictors) and authentication system groups (from eg Cognito).在第一个条件 (a) 中,您可以根据某种policies (资源访问限制器)和authentication system groups (例如 Cognito)设置访问选定模块(JavaScript 文件)的policies

In second condition (b) it depends on your backend.在第二个条件 (b) 中,它取决于您的后端。 Short Spring Boot solution is described above.上面描述了简短的 Spring Boot 解决方案。

Why would you need to protect your module?为什么需要保护模块?

It would be best to do not put any fragile part of your code in fronted application but even though you may deliver in your code some sort of informations which may leverage further attacks (eg social engineering attack).最好不要将代码的任何脆弱部分放在前端应用程序中,但即使您可能在代码中提供某种可能会利用进一步攻击(例如社会工程攻击)的信息。 So generally it is best to narrow permissions as much as it is possible and allow users as little as it is necessary for them.因此,通常最好尽可能地缩小权限,并尽可能少地允许用户。

Sources来源

[1] https://angular.io/cli/build [1] https://angular.io/cli/build

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法使用库中的嵌套延迟加载模块构建 angular 8 应用程序 - Cannot build angular 8 application with nested lazy-loaded module in library 组件无法从延迟加载的模块中找到提供程序 - component can't find provider from lazy-loaded module 来自延迟加载组件的 Angular 2+ 访问/更改变量 - Angular 2+ Access/Change Variable from Lazy-Loaded component 将 Angular 从 8 更新到 9 后延迟加载的模块警告 - Lazy-loaded modules warnings after updating Angular from 8 to 9 从延迟加载的文件延迟加载时发生错误-angular.js - Error when lazy-loading from a lazy-loaded file - angular.js Angular2 with Typescript,如何在延迟加载的模块中使用Plupload CDN脚本文件? - Angular2 with Typescript, how to use Plupload CDN script file in lazy-loaded module? 如何从延迟加载的模块访问 AppModule 模块导入? - How do I Access AppModule Module imports from Lazy-loaded Modules? 在从外部JSON文件构造的模板中使用延迟加载的Angular 2组件 - Consuming lazy-loaded Angular 2 components in a template constructed from an external JSON file Vue路由器仅显示一次延迟加载的路由组件 - Vue router shows lazy-loaded route components only once 对于延迟加载的模块,Angular onSameUrlNavigation - Angular onSameUrlNavigation for a lazy loaded module
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM