arrow-left

All pages
gitbookPowered by GitBook
1 of 3

Loading...

Loading...

Loading...

Policy Plugin

hashtag
D. Access Control Policy

  },

์œ„์— ์ •์˜ํ•œ ๊ฐ ํ”„๋กœํ† ์ฝœ๋“ค์˜ ์—”๋“œํฌ์ธํŠธ๋Š” ์„œ๋น„์Šค ๋ธŒ๋กœ์ปค์˜ call, publish, subscribe ์ปค๋„ฅํ„ฐ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๊ฐ ์ปค๋„ฅํ„ฐ๋“ค์— ๋Œ€ํ•ด์„œ ์ ‘๊ทผ ์ œ์–ด ์ •์ฑ…์„ ์ •์˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  policy: {

์ ‘๊ทผ ์ œ์–ด ์ •์ฑ…์€ ๋จผ์ € ํ˜ธ์ถœํ•˜๋Š” ์ปค๋„ฅํ„ฐ์— ๋”ฐ๋ผ์„œ action์ด๋‚˜ event์˜ ์ด๋ฆ„์œผ๋กœ ํ•„ํ„ฐ๋ง๋ฉ๋‹ˆ๋‹ค. ์—ฐ๊ด€๋œ ์ •์ฑ…๋“ค์€ ์ˆœ์„œ๋Œ€๋กœ ๋ชจ๋‘ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ •์ฑ…์„ ํ†ต๊ณผํ•˜๋Š” ๊ฒฝ์šฐ์— ํ•ด๋‹น ์ปค๋„ฅํ„ฐ๊ฐ€ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ ‘๊ทผ ์ œ์–ด ์ •์ฑ…์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์€ ํ”Œ๋Ÿฌ๊ทธ์ธ ํ˜•ํƒœ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ OAuth scope ๋ฐฉ์‹(scopes)๊ณผ Inline JavaScript Function String๋ฅผ ํ™œ์šฉํ•œ FBAC ๋ฐฉ์‹(filter) ๋‘๊ฐ€์ง€๊ฐ€ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

Caching: TODO

๋˜ํ•œ ์ ‘๊ทผ ์ œ์–ด ์ •์ฑ…์˜ ํ‰๊ฐ€๋Š” Gateway์˜ ๋ฉ”๋ชจ๋ฆฌ์— LRU ๋ฐฉ์‹์œผ๋กœ ์บ์‹œ๋˜๋ฉฐ ํ•œ ์š”์ฒญ์—์„œ ์ค‘๋ณต ์ˆ˜ํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์บ์‹œ ํ‚ค๋ฅผ ์ƒ์„ฑ ํ•  ๋•Œ ์š”์ฒญ์„ ์ •ํ™•ํžˆ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ปจํ…์ŠคํŠธ(์ธ์ฆ ์ •๋ณด) ๋ฐ ํ˜ธ์ถœ ํŽ˜์ด๋กœ๋“œ ๋“ฑ์˜ ์ •๋ณด๊ฐ€ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค.

Filter

Filter

        filter: `({ action, params, context, util }) => {
          if (action === "player.remove") {
            return context.user.player.isAdmin && context.user.player.id != params.id;
          } else if (action === "player.create") {
            return context.user && (!context.user.player || context.user.player.isAdmin); 
          }
          return true;
        }`,
      },

๋‹ค์Œ์œผ๋กœ filter ์ ‘๊ทผ ์ œ์–ด ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋”ฐ๋ผ action|event, params, context, util์„ ์ฃผ์ž…ํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉฐ, true ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒฝ์šฐ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค. FBAC์€ ACL์ด๋‚˜ RBAC์ฒ˜๋Ÿผ ๋Œ€์ค‘ํ™”๋˜์ง€๋Š” ์•Š์•˜์œผ๋‚˜, ABAC์˜ ํ™•์žฅ ๋ชจ๋ธ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ์œ ์—ฐํ•˜์—ฌ ๋ถ„์‚ฐ ํ™˜๊ฒฝ์— ์ ํ•ฉํ•˜๋ฉฐ ํ”„๋กœ๋•์…˜์—์„œ ๊ฒ€์ฆ๋œ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

filter ์ ‘๊ทผ์ œ์–ด ํ”Œ๋Ÿฌ๊ทธ์ธ ์—ญ์‹œ map ์ปค๋„ฅํ„ฐ์ฒ˜๋Ÿผ Gateway์˜ Node.js VM ์ƒŒ๋“œ๋ฐ•์Šค์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. filter ํ•จ์ˆ˜๋ฅผ ํ‰๊ฐ€ํ•˜๋Š” ์ค‘์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ๋””๋ฒ„๊ทธ ๋ฉ”์‹œ์ง€๊ฐ€ Gateway์—์„œ ์ถœ์ฒ˜ ๋…ธ๋“œ๋กœ ์ „๋‹ฌ๋˜๋ฉฐ ์ ‘๊ทผ์ด ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.

์œ„์ฒ˜๋Ÿผ player ์„œ๋น„์Šค์˜ API ์Šคํ‚ค๋งˆ๋Š” ๊ผญ player ์„œ๋น„์Šค์˜ ์•ก์…˜๋งŒ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ player API์—์„œ ๋…ธ์ถœํ•˜๋Š” team ์„œ๋น„์Šค์˜ ์•ก์…˜์— ๋Œ€ํ•œ ์ ‘๊ทผ ์ œ์–ด ์—ญ์‹œ player ์Šคํ‚ค๋งˆ์—์„œ ์ •์˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

publish, subscribe ์ปค๋„ฅํ„ฐ์˜ ์ •์ฑ…์—๋Š” actions ๋Œ€์‹  events ํ•„๋“œ๊ฐ€ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค.

์œ„์ฒ˜๋Ÿผ filter๊ฐ€ ์ƒ๋žต๋œ ๊ฒฝ์šฐ scopes๋งŒ ์ ์šฉ๋˜๋ฉฐ filter๋Š” ํ†ต๊ณผํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค.

์ ‘๊ทผ์ œ์–ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์€ ์œ„ ์ •์ฑ…์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

๋””๋ฒ„๊น… ์ค‘์— Inline JavaScript Function String์—์„œ console ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ, ๊ทธ ๋ฉ”์„ธ์ง€๋Š” Gateway์˜ VM ์•ˆ์—์„œ ์ถœ๋ ฅ๋˜์ง€ ์•Š๊ณ  Gateway๊ฐ€ ์ถœ์ฒ˜ ๋…ธ๋“œ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

      {
        description: "player can get associated team, admin can get all the teams",
        actions: ["team.get"],
        scopes: ["player", "player.admin"],
        filter: (({ action, params, context, util }) => {
          if (context.user.player.isAdmin || params.id === context.user.player.teamId) {
            return true;
          }
          return false;
        }).toString(),
      },
    ],
    publish: [
      {
        description: "Only admins can publish player events",
        events: ["player.**"],
        scopes: ["player"],
        filter: (({ event, params, context, util }) => {
          return context.user.player.isAdmin;
        }).toString(),
      },
    ],
    subscribe: [
      {
        events: ["player.**"],
        description: "Any user can receive player events",
        scopes: ["openid"],
      },
    ],
  },
}
{
  actions: ["**"],
  scopes: ["**"],
  filter: `() => true`,
}
{
  actions: ["**"],
  scopes: ["**"],
  filter: `(action, params, context) => {
    console.log("policy filter", action, params, context);
  }`,
}

Scope

Scopes

    call: [
      {
        description: "admin can remove player, newbie and admin can create player",
        actions: ["player.**"],
        scopes: ["player", "player.admin"],

์œ„ ์ •์ฑ…์€ player.** ํŒจํ„ด(player.get, player.list, player.message.list ๋“ฑ๊ณผ ์ผ์น˜)์˜ ์•ก์…˜์„ ํ˜ธ์ถœํ•˜๋Š” call ์ปค๋„ฅํ„ฐ๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ์—”๋“œํฌ์ธํŠธ๊ฐ€ ์ˆ˜ํ–‰๋˜๊ธฐ ์ „์— ๊ณตํ†ต์ ์œผ๋กœ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์šฐ์„  scopes ์ ‘๊ทผ ์ œ์–ด ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋”ฐ๋ผ context์— ์ฃผ์ž…๋œ (moleculer-iam ๊ฐ™์€ ์ปจํ…์ŠคํŠธ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด) OAuth ํ† ํฐ์ด ํš๋“ํ•œ ์Šค์ฝ”ํ”„๋ฅผ ํ™•์ธํ•˜๊ณ  ์ผ์น˜๋˜๋Š” ์Šค์ฝ”ํ”„๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ์žˆ๋Š” ๊ฒฝ์šฐ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค.