요약
CQRS / DDD의 권한 부여는 명령 / 조회마다 구현되어야합니까?
DDD CQRS 패턴을 다소 엄격하게 사용하는 온라인 응용 프로그램을 처음으로 개발하고 있습니다. 나는 약간의 문제에 부딪쳤다.
내가 만들고있는 응용 프로그램은 사람들이 원장을 만들 수있게하고 직원과 같은 다른 사람들이보고 / 편집 / 삭제할 수 있도록하는 원장 응용 프로그램입니다. 원장의 작성자는 자신이 작성한 원장의 액세스 권한을 편집 할 수 있어야합니다. 소유권을 바꿀 수도 있습니다. 도메인에는 두 개의 집계 TLedger 및 TUser가 있습니다.
보안, 권한 부여 등에 관한 DDD / CQRS 키워드로 많은 게시물을 읽었습니다 . 보안 응용 프로그램을 작성하지 않는 한 대부분은 권한 부여가 Generic Subdomain 이라고 언급했습니다 .
이 경우 핵심 도메인 은 거래, 밸런싱 및 계정에 관심이 있는 회계 도메인 입니다. 그러나 원장에 대한 세분화 된 액세스를 관리 할 수있는 기능도 필요합니다. DDD / CQRS 용어로 이것을 디자인하는 방법이 궁금합니다.
명령은 어디에서나 유비쿼터스 언어의 일부라고 DDD 튜토리얼에 나와 있습니다. 그들은 의미가 있습니다. 그것들은 "실제"를 나타내는 구체적인 행동입니다.
이러한 모든 명령과 쿼리는 사용자가 "실제"로 실행하는 실제 작업이므로 권한 부여 구현은 이러한 모든 "명령"및 "쿼리"와 결합되어야합니까? 예를 들어, 사용자에게는 TLedger.addTransaction ()을 실행할 권한이 있지만 TLedger.removeTransaction ()은 없습니다. 또는 사용자는 "getTransactions ()"가 아닌 "getSummaries ()"쿼리를 실행할 수 있습니다.
3 차원 매핑은 액세스 권한을 결정하기 위해 user-ledger-command 또는 user-ledger-query 형식으로 존재합니다.
또는 분리 된 방식으로 "permissions"라는 이름이 사용자에게 등록됩니다. 그런 다음 특정 명령에 대해 매핑되는 권한 예를 들어 권한 "ManageTransactions"는 사용자가 "AddTransaction ()", "RemoveTransaction ()"등을 실행할 수 있도록합니다.
권한 매핑 사용자-> 원장-> 명령 / 쿼리
권한 맵핑 사용자-> 원장-> 권한-> 명령 / 조회
이것이 질문의 첫 번째 부분입니다. 즉, CQRS / DDD의 권한 부여는 명령 또는 쿼리마다 구현되어야합니까? 또는 권한을 명령에서 분리해야합니까?
둘째, 권한 기반 인증에 관한 것입니다. 사용자는 자신의 원장 또는 자신이 관리 할 수있는 원장에 대한 권한을 관리 할 수 있어야합니다.
- 원장에서 권한 부여 관리 명령이 발생합니다
grantPermission (), revokePermission () 등과 같은 이벤트 / 명령 / 처리기를 Ledger 집계 에 추가하려고 생각했습니다 .이 경우 해당 규칙을 적용하면 명령 처리기에서 발생합니다. 그러나이를 위해서는 모든 명령에 해당 명령을 발행 한 사용자의 ID가 포함되어야합니다. 그런 다음 해당 사용자가 해당 명령을 실행할 수있는 권한이 있는지 TLedger에 체크인합니다.
예를 들면 다음과 같습니다.
class TLedger{
function addTransactionCmdHandler(cmd){
if (!this.permissions.exist(user, 'addTransaction')
throw new Error('Not Authorized');
}
}
- 사용자의 권한 관리 명령
다른 방법은 권한을 TUser에 포함시키는 것입니다. TUser는 권한 세트를 갖습니다. 그런 다음 TLedger 명령 핸들러에서 사용자를 검색하여 명령을 실행할 권한이 있는지 확인합니다. 그러나 이것은 모든 TLedger 명령에 대해 TUser 집계를 가져와야합니다.
class TAddTransactionCmdHandler(cmd) {
this.userRepository.find(cmd.userId)
.then(function(user){
if (!user.can(cmd)){
throw new Error('Not authorized');
}
return this.ledgerRepository.find(cmd.ledgerId);
})
.then(function(ledger){
ledger.addTransaction(cmd);
})
}
- 서비스가있는 다른 도메인
또 다른 가능성은 다른 권한 부여 도메인을 완전히 모델링하는 것입니다. 이 도메인은 액세스 권한, 권한 부여 등에 관심이 있습니다. 계정 하위 도메인은 서비스를 사용하여이 권한 부여 도메인에 액세스합니다 AuthorizationService.isAuthorized(user, command)
.
class TAddTransactionCmdHandler(cmd) {
authService.isAuthorized(cmd)
.then(function(authorized){
if (!authorized) throw new Error('Not authorized');
return this.ledgerRepository.find(cmd.ledgerId)
})
.then(function(){
ledger.addTransaction(cmd);
})
}
가장 "DDD / CQRS"방식은 무엇입니까?