日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自动化用户特定实体的访问控制

發(fā)布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自动化用户特定实体的访问控制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

實際上,每個Web應(yīng)用程序都應(yīng)該有多個用戶,每個用戶都有一些數(shù)據(jù)-帖子,文檔,消息等等。 最明顯的事情是保護(hù)這些實體免遭非這些資源合法所有者的用戶獲取。

不幸的是,這不是最容易的事情。 我并不是說很難,它不像簡單地返回資源那樣直觀。 當(dāng)您是/record/{recordId}端點時,您將立即執(zhí)行對recordId的數(shù)據(jù)庫查詢。 只有這樣,才需要檢查此記錄是否屬于當(dāng)前經(jīng)過身份驗證的用戶。

框架在這里沒有幫助,因為這種訪問控制和所有權(quán)邏輯是特定于域的。 沒有明顯的通用方法來定義所有權(quán)。 它取決于實體模型和實體之間的關(guān)系。 在某些情況下,它可能非常復(fù)雜,需要在聯(lián)接表中查找(對于多對多關(guān)系)。

但是您應(yīng)該自動執(zhí)行此操作,原因有兩個。 首先,在每個端點/控制器方法上手動執(zhí)行這些檢查很繁瑣,并且使代碼難看。 其次,更容易忘記添加這些檢查,尤其是在有新開發(fā)人員的情況下。

您可以在DAO的所有地方進(jìn)行這些檢查,但通常應(yīng)盡早失敗,因此這些檢查應(yīng)在控制器(端點處理程序)級別上進(jìn)行。 對于Java和Spring,可以使用批注和HandlerInterceptor來自動執(zhí)行此操作。 在使用任何其他語言或框架的情況下,也可以使用類似的方法-一種可插拔的方式來描述要檢查的所有權(quán)關(guān)系。

以下是放置在每個控制器方法上的示例注釋:

public @interface VerifyEntityOwnership {String entityIdParam() default "id";Class<?> entityType(); }

然后定義攔截器(當(dāng)然,應(yīng)將其配置為執(zhí)行)

@Component public class VerifyEntityOwnershipInterceptor extends HandlerInterceptorAdapter {private static final Logger logger = LoggerFactory.getLogger(VerifyEntityOwnershipInterceptor.class);@Autowiredprivate OrganizationService organizationService;@Autowiredprivate MessageService MessageService;@Autowiredprivate UserService userService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {Authentication authentication = SecurityContextHolder.getContext().getAuthentication();// assuming spring-security with a custom authentication token typeif (authentication instanceof ApiAuthenticationToken) {AuthenticationData authenticationData = ((ApiAuthenticationToken) authentication).getAuthenticationData();UUID clientId = authenticationData.getClientId();HandlerMethod handlerMethod = (HandlerMethod) handler;VerifyEntityOwnership annotation = handlerMethod.getMethodAnnotation(VerifyEntityOwnership.class);if (annotation == null) {logger.warn("No VerifyEntityOwnership annotation found on method {}", handlerMethod.getMethod().getName());return true;}String entityId = getParam(request, annotation.entityIdParam());if (entityId != null) {if (annotation.entityType() == User.class) {User user = userService.get(entityId);if (!user.getClientId().equals(clientId)) {return false;}} else if (annotation.entityType() == Message.class) {Message record = messageService.get(entityId);if (!message.getClientId().equals(clientId) {return false;}} // .... more}}return true;}@SuppressWarnings("unchecked")private String getParam(HttpServletRequest request, String paramName) {String value = request.getParameter(paramName);if (value != null) {return value;}Map<String, String> pathVariables = (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);return pathVariables.get(paramName);} }

您會看到這假定每種類型都需要自定義邏輯。 如果您的模型很簡單,則可以使之通用–使所有實體都使用它們都定義的getClientId()方法實現(xiàn)某些Owned接口。 然后只需要一個dao.get(id, entityClass); 并避免使用特定于實體的邏輯。

請注意,當(dāng)方法上沒有注釋時,將顯示警告-那里表示您可能已經(jīng)忘記添加一個。 某些端點可能不需要所有權(quán)檢查-對于它們,您可以具有特殊的@IgnoreEntityOwnership批注。 關(guān)鍵是要做出有意識的決定,以不驗證所有權(quán),而不是忘記所有權(quán)并引入安全問題。

我的意思可能很明顯。 但是我已經(jīng)看到了許多這種遺漏的例子,包括生產(chǎn)政府項目。 正如我說的,框架不會強(qiáng)迫您考慮這一方面,因為它們不能以通用的方式做到這一點– Web框架通常與您的實體模型無關(guān),而ORM與您的控制器無關(guān)。 有處理所有這些方面的綜合框架,但是即使它們沒有通用的機(jī)制 (至少我不知道)。

安全性包括對系統(tǒng)應(yīng)用一套良好的實踐和原則。 但是,它還包括一些程序和自動化程序,這些程序和自動化程序可以幫助開發(fā)人員和管理員不要忽略他們通常知道的東西,而會時不時地忘記。 而且,應(yīng)用安全性原則越乏味,則一貫應(yīng)用安全性原則的可能性就越大。

翻譯自: https://www.javacodegeeks.com/2018/10/automate-access-control-user-entities.html

總結(jié)

以上是生活随笔為你收集整理的自动化用户特定实体的访问控制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。