- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我是 stack overflow 的常客,但这是我的第一个问题。
我正在使用 OAuth2 规范开发授权服务器。我只是被困在如何在使用密码流的同时确保第一方客户端的真实性上。我阅读了很多论坛,这就是我得到的:
Javascript 单页客户端
Alex Bilbie 的这篇博文,他指出,为了避免 client_secret 问题,我们应该:
It’s simple; proxy all of your API calls via a thin server side component. This component (let’s just call it a proxy from here on) will authenticate ajax requests from the user’s session. The access and refresh tokens can be stored in an encrypted form in a cookie which only the proxy can decrypt. The application client credentials will also be hardcoded into the proxy so they’re not publicly accessible either.
但是现在这个代理可以被冒充我的人访问 Angular 应用程序。然后我看到了 Andy 的这篇博文外野手:How Secure is the OAuth2 Resourc Owner Password Flow for Single Page Apps .他基本上说要依靠 CORS 来避免冒充 JS 客户端。
使用这两种方法来保护我的 JS 应用程序是个好主意吗?
本地应用(桌面和移动)
在移动应用的情况下,我只找到授权的情况代码和隐式流程。这不是我想要的,因为重定向会损害用户体验。所以我对此的看法是:
我将使用 ROP 流程,然后使用一个client_id
为这个特定的安装生成并附上它到用户帐户,接收 access_token
和client_secret
作为响应。由此发出的任何其他 token 请求客户端必须携带此凭据(因为 client_id
是特定的对于安装,我将能够检查此客户端是否已经认证)。这样,如果有人使用任何凭据冒充客户,甚至注册一个假客户,我可以采取撤销用户和客户端访问权限的措施。
我知道这可能是想多了,我也知道有些事情并不能避免任何事情。我只是觉得尽我所能保护我的 API 是我的工作。
我非常感谢您对此问题的看法!我真的是多虑了吗?我应该只使用“公共(public)客户”的概念并继续吗?
谢谢大家,祝编码愉快!
最佳答案
首先,这个问题不是一个常见的优先级,因为大多数应用程序都是先用网站开发的,然后再用 API 开发的。这可能是原因,因为没有人知道如何使用 oauth2 处理第一批客户,因为每个人都开发了其他方法来做到这一点,而只需要 oauth2 来授予用户对第三方应用程序的访问权限。
即使您仅为第一个客户端应用程序开发了 oauth2 授权服务器(考虑单一身份验证机制而不是开发多个),您也应该尝试开发授权代码或隐式授权类型。您会意识到您需要一种方法来检查实际登录的用户。
两种常用的方法是:
无论哪种方式,您都需要检查您的应用程序安全性,用户 session 易受 CSRF 攻击,localStorage 易受 XSS 攻击。有很多关于如何保护您的网站免受任何一种攻击的文章,所以我不会在这里提出任何建议,您只需要知道它们的存在即可。
既然您选择了身份验证方法,我们就可以开始考虑:
代理
在我看来,拥有一个过滤所有请求的代理就像有一扇总是插着 key 的门。建门也没用。但是,对于基于 session 的身份验证,这是唯一的方法。在 Rest API 上允许 session 身份验证会导致 CSRF 安全问题,因此您需要有一个代理层来获取用户 session 、从 session 中检索访问 token 并向 Rest API 添加 Authorization
标题。
CORS
使用此方法,您需要将用户访问 token 存储在 localStorage 中,因为 token 是直接从 Js 客户端检索的。
使用 CORS,您可以确定其他网站无法从浏览器向您的 Rest API 发出请求。但是您的第一个客户端需要公开(即:它没有 client_secret
)。
在我的第一个应用程序中,我尝试使用您建议的相同机制来保护身份验证流程。然而,这种机制要求您以唯一的方式识别每个用户客户端。这在 iOS 中是不可能的 privacy reasons并且有可能在未来的 Android 版本中被拒绝。因此,您应该依赖公共(public)客户端并在您的 native 应用程序代码中仅添加 client_id
。
也就是说你的native app client/你的js client可以非个性化?
是的,并且无法通过 oAuth2 资源所有者密码凭据授予类型来防止这种情况。
主要是因为oAuth2不是为了鉴权,只是为了第三方授权,并且添加了grant type只是为了特定的第三方应用可信到足以直接使用用户密码。你可以阅读更多关于这个论点的信息 here和 here .
您仍然需要一种方法来授权您的用户,我认为使用 oAuth2 可以实现的最佳效果是 Auth0做过。本质上,此 SaaS 使用 oAuth2 服务器 + OpenID 连接管理您的用户,因此您始终像管理第三方应用程序一样管理您的用户,并且一切正常。
的确,你可以在this page上看到对于移动应用程序,他们建议使用基于浏览器的登录表单,因为反编译您的应用程序的每个人都可以将原生表单非个性化,但如果您将其包装到授权代码流中,它就可以正常工作。
关于javascript - 公共(public)第一方客户端的正确 OAuth2 流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37200642/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: When should [assembly: InternalsVisibleTo()] be used?
问题与微服务有关,当我有多个微服务提供将被订购和计费的功能/服务时。 我正在确定采用哪种方法, a) 每个可计费微服务有一个订单和一个计费服务,有各自的数据库。b) 跨所有微服务的通用订单管理和计费服
我正在尝试使用 gcloud图书馆。 (ns firengine.state (:import [com.google.cloud AuthCredentials] [com.goog
Java 允许定义以下一对类。 class Class1 { ... } public Class2 { public Class2(Class1 c1) { ... } } 如果因为 Class1
我正在尝试查找文件 1 和文件 2 中的共同行。如果公共(public)行存在,我想写入文件 2 中的行,否则打印文件 1 中的非公共(public)行。fin1 和 fin2 是这里的文件句柄。它读
好吧,这是一个满口的标题。不过,这让我明白了。这是我的代码的要点,在 jar 里: public class NetworkShared { public static class Login
我在使用 ltree 时遇到 PHP 问题来自 PostgreSQL .我在 SQL 中这样做: SELECT * FROM tabla t WHERE t.parent_path " for "OP
我知道如何为类/接口(interface)/包的子集生成 Javadoc。但是有没有办法只为公共(public)方法的一个子集生成 Javadoc? 我更喜欢能够将方法(Javadoc 标记或注释)标
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicates: c#: why have empty get set properties instead of usin
在我们的每个项目中,都有一个文件用于存储该项目中使用的各种SQL 语句。类的声明方式和字符串的声明方式有一些变化。 示例类声明: internal sealed class ClassName int
我根据 http://docs.jquery.com/Plugins/Authoring 定义了我的插件 (function( $ ){ var methods = { init : fu
我正在使用 Inno Setup 来构建我的安装程序,我有 C:\Users\Public文件夹硬编码在我的 [Files] 中放置一些文件的部分(Inno Setup 没有此文件夹的常量) 我的目标
我有一个 dataframe1 包含像 'ID', 'A', 'B', 'C', 'D', 'E', 'F', 'G' 这样的列. 现在,我创建了两个数据框, dataframe2 包含 'ID',
我有一个抽象类,不幸的是我无法更改它的定义,它基本上提供了一个抽象方法,有点像。 public abstract void do(Data someData, BaseInterface interf
我刚刚在重构时偶然发现了一段奇怪的代码。它看起来像是分解出两个 readString() 方法的共同部分的候选者,只是它似乎是不可能的(这对我来说是一个令人毛骨悚然的脑筋急转弯): private f
是否有解析为公用文件夹的属性?显然,我不想在目录结构中对“c:\users\public”进行硬编码,但我找不到预定义的 Property解决这个问题。是否有一种可接受的方式来指定要在此处安装和/或在
我试图将值从一个类传递到另一个类。 subPanel1 类读取全局变量,但当我通过调整监听器更新这些变量时,它不会更改值。我试图将 rc、gc 和 bc 变量从 subPanel2 类传递到 subP
我想使用具有自动属性的干净且编码较少的类。所有属性(property)都是公共(public)的。在同一类的方法中我也使用了该属性。因此,我认为这种方法是可混搭的,因为我将公共(public)属性用于
不久前,我在 Android 应用程序中创建了一个 SQLiteHelper 类。我不是 100% 确定原因,但表名和列名是嵌套公共(public)静态抽象类中的公共(public)静态最终字段。我记
这个问题已经有答案了: Cannot make a static reference to the non-static method (8 个回答) 已关闭 3 年前。 我正在为类(class)做一
我是一名优秀的程序员,十分优秀!