Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AuthzCtx - Alp社内共有会

AuthzCtx - Alp社内共有会

Alp社内共有会用

C6a8cb5e13aa716521d522471ec4e4cd?s=128

ma2k8
PRO

April 22, 2022
Tweet

More Decks by ma2k8

Other Decks in Technology

Transcript

  1. Authz 2 0 2 2 / 0 4 / 2

    2 υ ϝ Π ϯ ڞ ༗ ձ M A C H U
  2. 2 ΞδΣϯμ • ೝՄ೉͍͠ͱ͜Ζ͓͞Β͍ • ೝՄج൫v1ͰରԠ͍ͯͨ͠෦෼͓͞Β͍ • v1ͰԿ͕Ͱ͖͍ͯͳ͔͔ͬͨ • Scope෇༩ํ๏ղઆ

    • ࡉ͔͍࢓૊Έ • ϑϩϯτͱͷ΍ΓͱΓ • SATͷ࡞Γํ • ࠓޙͷԠ༻ • ࠷ޙʹ
  3. 3 ೝՄ೉͍͠ͱ͜Ζ͓͞Β͍

  4. 4 ೝՄͷ೉͍͠఺ ద༻ൣғ͕޿͍ Operator,System,Token,֤ Ctx,Adpt,UseCase,Domain etc… ೝՄͷ֓೦͕ᐆດͰɺ ѻ͍͕೉͍͠ ϩδοΫͱ ີʹͳΓ΍͍͢

  5. 5 ద༻ൣғ͕޿͍ Presenter Controller Repository(DB etc..) UseCase Domain Masking item

    Execute endpoint Filter resource read/write auhorization Execute UseCase Ramification domainLogic Execute domainLogic ֤૚ͰೝՄΛద༻͍ͨ͠৔໘͕͜Ε͚ͩ͋Γ·͢ɻ͜ΕΒΛผʑͷ࢓૊ΈͰ࣮૷ͯ͠͠·͏ͱ ख਺͕ଟ͘ͳΓ͗͢Δ͠ɺ࢓૊Έಉ࢜ͷ੔߹ੑΛઁΔ͜ͱ΋೉͘͠ͳΓ·͢ɻ
  6. 6 ద༻ൣғ͕޿͍ Presenter Controller Repository(DB etc..) UseCase Domain Presenter Controller

    Repository(DB etc..) UseCase Domain Presenter Controller Repository(DB etc..) UseCase Domain Ctx-A Ctx-B Ctx-C ͔͠΋ɺͦͷ૚͕ෳ਺ͷίϯςΩετʹ·͕ͨΓ·͢ɻ ౷ҰతʹऔΓѻ͏ೝՄج൫͕ͳ͍ͱख਺͕૿͑͗͢Δ͠ɺظ଴ͨ͠ڍಈΛಘΔͷ΋อͭͷ΋೉͘͠ͳΓ·͢ɻ ·ͨɺॲཧͷϑϩʔ΋ෳࡶԽ͕ͪ͠Ͱ͢ɻ
  7. 7 ೝՄͷ֓೦͕ᐆດͰɺѻ͍͕೉͍͠ Presenter Controller Repository(DB etc..) UseCase Domain Masking item

    Execute endpoint Filter resource read/write auhorization Execute UseCase Ramification domainLogic Execute domainLogic ͜Ε͚֤ͩ૚ʹ͓͍༷ͯʑͳ࡞༻͕͋ΔͷͰɺͲͷΑ͏ͳ֓೦ͱͯ͠औΓѻ͏͔೉͍͠໰୊͕ ͋Γ·͢ɻ
  8. 8 ϩδοΫͱີʹͳΓ΍͍͢ ୯७ʹॻ͘ͱɺݖݶ͕ଘࡏ͢Δ͔ͷνΣοΫΛ৭ʑͳͱ͜Ζʹ࢓ࠐΉ͜ͱʹͳΓ·͢ `If (Operator.policy. fi nd(_ == CanWriteContract)) ~

    ` ͱ͍ͬͨ۩߹Ͱ͢ɻ ͜Ε͚ͩͳΒ·ͩϚγͰ͕͢ɺ࣮ࡍ͸ `If ( (Operator.policy.exixts(_ == AllAllow) || Operator.policy.exixts(_ == CanWriteContract)) && Operator.policy.exixts(_ != AllDeny)) )` ͳͲɺͲΜͲΜංେԽ͍͖ͯ͠ɺͦΕ͕৭ʑͳͱ͜Ζʹࢄ Β͹ͬͯ͠·͍·͢ɻϑϩϯτʹ·ͰඈͼՐͯ͠ີʹͳΓ·͢ɻ
  9. 9 ೝՄج൫v1ͰରԠ͍ͯͨ͠෦෼͓͞Β͍

  10. 1 0 ෼ੳػೳ΁෦෼తʹద༻͍ͯͨ͠ೝՄج൫v1Ͱ ΋ɺ͜ΕΒͷ໰୊ʹ͸͋Δఔ౓ରԠͰ͖͍ͯͨ

  11. 11 ద༻ൣғ͕޿͍ Operator,System,Token,֤ Ctx,UseCase,Domain etc… ൒؀ߏ଄ʹΑΔॊೈͳදݱ PrincipalIdʹΑΔೝՄओମந৅Խ

  12. 1 2 AuthzCtxͷ੾Γग़͠ͱɺ ೝՄؔ࿈Ϟσϧͷlib഑ஔ ೝՄͷ֓೦͕ᐆດͰɺ ѻ͍͕೉͍͠

  13. 1 3 - EffͰͷΤϑΣΫτந৅ԽʹΑΔؔ৺෼཭ - AuthzCtx෼཭ʹΑΔɺSupport,Manage,Decideͱɺ Enforceͷ෼཭ ϩδοΫͱີʹͳΓ΍ ͍͢

  14. 1 4 Support,Manage,DecideͱɺEnforceͷ෼཭ͱ͸ ‘XACML Reference Architecture’ ʹ ͋Δ஌ݟͰɺೝՄͷ෼཭ͷ୯ҐΛ͜ͷ4ͭʹ෼͚͍ͯΔ ScalebaseͰ͸ Decide,ManageΛAuthzCtxʹด͡ࠐΊɺAuthzIOͰૢ

    ࡞ͷίϚϯυΛΤϑΣΫτந৅Խ Enforce,Support͸جຊతͳ൑ఆ͸AuthzCtxʹدͤɺ BooleanΛฦ͢͜ͱʹΑͬͯ൒؀ߏ଄Λར༻֤ͯ͠Ctx Ͱͷ൑ఆͱ߹੒ͯ͠൑ఆ͕Ͱ͖ΔΑ͏ʹ͍ͯ͠Δ ※Support͸AuthzCtxܦ༝ʹ͢Δύλʔϯ΋͋ΔͷͰ ࠓޙศརͳํΛબ୒͍ͯ͘͠
  15. 1 5 ͜ͷล͸👇ͷࢿྉΛࢀর͍ͩ͘͞🙏 https://speakerdeck.com/ma2k8/authz

  16. 1 6 v1ͰԿ͕Ͱ͖͍ͯͳ͔͔ͬͨ

  17. 1 7 ͡Ό͋Կ͕Ͱ͖ͯͳ͔ͬͨΜ͚ͩͬ

  18. 1 8 ೝՄج൫v1ͷΧόʔൣғ Presenter Controller Repository(DB etc..) UseCase Domain Masking

    item Execute endpoint Filter resource read/write auhorization Execute UseCase Ramification domainLogic Execute domainLogic
  19. 1 9 ೝՄج൫v2(ࠓ΍ͬͯΔ΍ͭ)ͷΧόʔൣғ Presenter Controller Repository(DB etc..) UseCase Domain Masking

    item Execute endpoint Filter resource read/write auhorization Execute UseCase Ramification domainLogic Execute domainLogic ※͜͜͸PresenterΛEffʹੵΊ͹Ͱ͖ΔΑ͏ʹͳΔ
  20. 2 0 ࠩ෼ Execute endpoint read/write auhorization Execute UseCase ͕

  21. 2 1 ͷঢ়ଶͱ͸ දݱ͸Ͱ͖Δ͕ɺہॴతͳݖݶ൑ఆ͕͔ͳ Γͷྔʹͳͬͯ͠·͍ɺӡ༻͕ਏ͍ for { hasViewerPermission <- AuthzIO.requestBoolPolicy[R](

    ActionComposing.Literal( principalId = operatorId.toPrincipalId, action = DashboardAnalysisView, resourceIds = Nil ) ) hasExplorerPermission <- AuthzIO.requestBoolPolicy[R]( ActionComposing.Literal( principalId = operatorId.toPrincipalId, action = DashboardAnalysisExplore, resourceIds = Nil ) ) lookerRole <- fromPpError[R, LookerRole] { if (hasViewerPermission) Right(SimpleViewer) else if (hasExplorerPermission) Right(SimpleExplorer) else Left(PpError.UnauthorizedError()) } …
  22. 2 2 ࠓճͷཁ݅

  23. 2 3 ReadOnlyͳݖݶ

  24. 2 4 ద༻ൣғ͕޿͍ʂ

  25. 2 5 ·͞ʹɹ͕ϒοࢗ͞Δཁ݅

  26. 2 6 ͜Ε·ͰͷScalebaseͷॲཧશͯʹ ͜ͷ෼ذΛ଍͢ͷ͸ɺେਓ਺Ͱ͔͠ճͤͳ͍γεςϜ΁ͷ ೖΓޱͱͳΓ͏Δ͠ɺγϯϓϧʹઈରόάΔɻආ͚͍ͨɻ

  27. 2 7 υϝΠϯϩδοΫͷݖݶ൑ఆ΍෼ذ͸ʮہॴతͰͳ͚Ε͹ͳΒͳ͍ʯ͕ɺ ΑΓେ͖ͳείʔϓతͳ֓೦͸ɺ೚ҙͷείʔϓΛઃఆͨ͠Βউखʹద༻͞Εͯ΄͍͠ͳ͊ ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ

  28. 2 8 ࡞Γ·ͨ͠

  29. 2 9 Scope෇༩ํ๏ղઆ

  30. 3 0 ·ͣ͸Contractʹ είʔϓ෇༩͢ΔܗͰղઆ͠·͢

  31. 3 1 ؆୯ 4εςοϓ

  32. 3 2 ᶃContractͷRead/WriteʹඞཁͳScopeΛ෇༩ implicit val scopeAllocator: ScopeAllocator[ContractId] = ScopeAllocator.allocate( readScope

    = List(Action.ContractRead), writeScope = List(Action.ContractWrite) ) domain૚ʹ͋ΔɺContractIdͱContractͷίϯύχΦϯΦϒδΣΫτʹscopeAllocatorΛઃఆ͠ ·͢ɻ
  33. 3 3 ᶄContractRepositoryͷγάχνϟʹͯ ฦΓ஋ΛࢦఆͷܕͰғ͏ def findById[R: _authzio: _trantask]( providerId: ProviderId,

    id: ContractId ): Eff[R, ReadAuthzScopeRepoFilter[Option[Contract]]] def store[R: _authzio: _trantask: _clockm: _ppErrorEither]( entity: Contract ): Eff[R, WriteAuthzScope[Contract]] ReadScopeΛར༻͢ΔRepositoryͷϝιου͸ ReadAuthzScopeRepoFilterɺ WriteScopeΛར༻͢Δϝιου͸ɺWriteAuthzScope Ͱғ͍·͢ Repository͸ɺ͜ͷΠϯλʔϑΣʔεʹͳ͍ͬͯͳ͍ͱίϯύΠϧΤϥʔʹ͢Δscala fi xϧʔϧ ΋༻ҙͯ͠ΔͷͰྑ͖λΠϛϯάͰద༻͍͖͍ͯͨ͠ͱࢥ͍ͬͯ·͢ɻ
  34. 3 4 ᶅContractRepositoryImplʹͯ ࢦఆͷܕͰғͬͯฦ͢ // ReadScopeͷ෇༩͸ A => ReadAuthzScopeRepoFilter[A] yield

    ReadAuthzScopeRepoFilter(maybe) // WriteScopeͷ෇༩͸ A => Eff[R, WriteAuthzScope[A]] contract <- fromPpError(stored.toRight(ResourceNotFoundError(resourceName = "contract", identifier = entity.id))) contractWithScope <- WriteAuthzScope(contract) Write͸ɺReadAuthzScopeRepoFilter.apply ͰWriteAuthzScopeͰแΉࡍʹscopeΛ෇༩͍ͯ͠ΔͷͰ A => Eff[R, WriteAuthzScope[A]] ͱͳΔͷͰforࣜ಺Ͱapply͠·͢ɻ Read͸ɺReadAuthzScopeRepoFilter. fi lteredValueͰ஋ΛऔΓग़͢ࡍʹscopeΛ෇༩͍ͯ͠ΔͷͰɺA => ReadAuthzScopeRepoFilter[A]ͱͳΔͷͰyieldͳͲͰapply͠·͢ɻ
  35. 3 5 ᶆ࠷ޙʹPrimaryAdapterͰrun! runAuthz or runAll Ͱ࣮ߦ͢ΔͱɺࢦఆͷScopeʹର͢ΔݖݶΛ͍࣋ͬͯͳ͚Ε͹ `ೝՄΤϥʔ` ʹͳΓ·͢ɻ BatchAdapterͰ͸ɺೝՄΛεΩοϓ͍ͨ͠ͷͰ

    runAuthzIOWithoutRequest or runAllWithoutAuthzIORequestͱ͢ΔͱೝՄΛεΩοϓ͢Δ͜ͱ΋Ͱ͖·͢ɻ
  36. 3 6 ͜Ε͚ͩͰ౷Ұతͳ είʔϓ੍͕ޚ͕ߦ͑·͢

  37. 3 7 ؆୯Ͱ͢Ͷʂ

  38. 3 8 Scopeͷࡉ͔͍࢓૊Έ

  39. 3 9 ScopeΛStateͰදݱ͠ɺ ΤϑΣΫτελοΫʹಥͬࠐΜͰ͍Δ ೝՄScope͕෇༩͞Ε͍ͯΔ͜ͱΛࣔ͢ܕΫϥεͷapply࣌ʹɺimplictlyͰScopeAllocatorΛಋग़ ͠ɺStateʹScopeΛੵΜͰ͍·͢ɻ

  40. 4 0 ݱঢ়͸RepositoryͷΈ͕ͩͲ͜Ͱ΋ੵΊΔ ͠ɺͲ͜ͰੵΜͰ΋ಉ͡StateͰ؅ཧͰ͖Δ Presenter Controller Repository(DB etc..) UseCase Domain

    Set Scope A Set Scope B Set Scope C,D Set Scope E Set Scope F State[List[A,B,C,D,E,F], X] ΋ͪΖΜɺෳ਺ͷRepositoryΛ࢖ͬͯ΋ͦΕͧΕͰඞཁͳScope͕ηοτ͞ΕͨState͕खʹೖΓ ·͢ɻ
  41. 4 1 Principal΋StateͰ؅ཧ͍ͯ͠Δ HttpAdapterͷOperatorExtractorͱ͍͏JWTτʔΫϯ͔ΒOperatorIdΛExtract͢ΔॲཧͷதͰɺ PrincipalΛηοτ͍ͯ͠·͢ɻ ݱঢ়͸OperatorͷΈͰ͕͢ɺTokenͳͲ΋͜ͷํ๏ͰTokenId(?)ͳͲΛηοτ͠·͢ɻ 
 _ <- AuthzIO.setPrincipal[R](operator.id.toPrincipalId)

  42. 4 2 runAuthzIO࣌ʹ ೝՄνΣοΫͷίϚϯυΛ࢓ࠐΉ Runͷॲཧ͸ɺࣜʹରͯ͠Ұ౓͔͠ߦΘΕͳ͍ͷͰೝՄνΣοΫͷ໋ྩΛڬΉλΠϛϯάͱ͠ ͔ͯͳΓద੾Ͱ͢ɻ͜ΕʹΑͬͯԣஅతͳείʔϓͷνΣοΫΛҰ౓ͷॲཧͰޮ཰తʹߦ͏͜ ͱ͕Ͱ͖·͢ɻ

  43. 4 3 ͋ͱ͸ೝՄνΣοΫͷίϚϯυ Λॲཧ͢Δ͚ͩ ೝՄRequestͷίϚϯυ಺ͰɺPrincipalIdͱScopeΛState͔ΒऔΓग़͠ɺPrincipalIdΛݩʹAuthzCtx͔Β AttachedPolicyΛऔಘ͠ɺScopeͱಥ߹͠ɺAllow/DenyΛ൑ఆ͠·͢ɻ RejectionͳͲͷॲཧ΋͋ΔͷͰׂͱෳࡶͰ͕͢ɺૄʹอ͍ͯͯ·͢ɻ(͜Ε͕֤ॴʹࢄΔͷ͸ׂͱ͋Γ͕ͪ…)

  44. 4 4 ౎౓ɺॲཧΛ଍ͨ͠Γมߋ͢ΔͨͼʹೝՄΛҙࣝ͢Δඞཁ͕ͳ͘ ͳΓɺυϝΠϯϞσϧ௥Ճ࣌ʹ͚ͩҙࣝ͢Ε͹Α͘ͳͬͨ υϝΠϯϞσϧ௥Ճ࣌΋ɺߟྀ͕࿙ΕͨΒίϯύΠϧΤϥʔͰݕ ஌Ͱ͖ΔΑ͏ʹͳͬͨ(scala fi x࠷ߴ)

  45. 4 5 Ϙϒ͓͡͞Μ͕ʮηΩϡϦςΟ͸ΞϓϦέʔγϣϯಛ༗ͷؔ৺͝ ͱͰ͋ΓɺϏδωεΦϒδΣΫτ͸͜ͷ͜ͱʹ͍ͭͯҙࣝ͠ͳ ͍ʯతͳ͜ͱΛݴ͍ͬͯ·͕ͨ͠ɺݸਓతʹ͸ʮͦͷέʔε΋͋ Γɺͦ͏Ͱͳ͍έʔε΋͋Δʯͱߟ͍͑ͯ·͢ɻ

  46. 4 6 υϝΠϯϩδοΫͷ෼ذ΍ɺॲཧ಺༰ͦͷ΋ͷʹؔ༩͢Δέʔε ͱɺϏδωεΦϒδΣΫτ͕ҙࣝ͠ͳͯ͘ྑ͍Scopeͱ͍͏ܗͷ ྆ํΛόϥϯεΑ͘දݱͰ͖͍ͯΔ

  47. 4 7 ϑϩϯτͱͷ΍ΓͱΓ

  48. 4 8 ·ͣ͸ FEͱBEͷೝՄͷϞνϕࠩ෼ʹ ͍ͭͯղઆ

  49. 4 9 BEͷೝՄͷϞνϕ - ೝՄ͸ઈରͷ੍໿ - ͜Ε͕कΒΕͳ͔ͬͨΒଈηΩϡϦςΟϦεΫ - ࠷ޙͷཁ

  50. 5 0 FEͷೝՄͷϞνϕ - Ϣʔβʔͷೝ஌ෆՄΛԼ͛ɺମݧΛΑ͘͢ΔͨΊʹBEଆͰઃఆ͞Ε͍ͯΔೝՄ৘ใΛར༻͠ ͍ͨ - ࡉ͔͍ೝՄଐੑ৘ใΛ஌Δඞཁ͸ͳ͘ɺʮΤϯυϙΠϯτ͕͚ͨͨΔݖݶΛ༗͢Δ͔൱͔ʯ ͘Β͍ͷཻ౓Ͱ෼͔Ε͹ɺίϯϙʔωϯτͷඇ׆ੑԽʹ࢖͑Δ -

    ࠷ѱɺඇ׆ੑԽ͞Εͳͯ͘΋BEଆͰೝՄΤϥʔͱͳΕ͹OK
  51. 5 1 BEଆͰ؅ཧ͍ͯ͠Δࡉ͔͍ೝՄଐੑΛFEͰ൑ఆʹ࢖͏ͱɺFE,BEͷ ີ݁߹ʹ΋ͭͳ͕ΓؾָʹೝՄଐੑΛมߋ͠ʹ͍͘ঢ়ଶʹͳΔɻ Կ͔Ұͭɺ͔·͍ͤͨ

  52. 5 2 ϑϩϯτଆ͕ղऍ͠΍͍͢ ܗʹೝՄ৘ใΛՃ޻͢Δ

  53. 5 3 SAT (Scalebase Authorization target)

  54. 5 4 ཁ͸IAMͷScalebase൛Ͱ͢ - ΤϯυϙΠϯτͱ1-1ͰରԠ͢ΔrouteNameͱɺprincipalͷ৘ใΛදݱ͠·͢

  55. 5 5 SATͷ࡞Γํ

  56. 5 6 ΤϯυϙΠϯτΛ௥Ճ͢Δࡍʹ RPCΛఆٛ͢Δ ͜Ε·Ͱɺrequest,response͚ͩఆٛͯ͠·͕ͨ͠ɺrpc΋ఆٛ͢ΔΑ͏ʹ͠·͢ɻ ͜ͷrpcͰBEͷRouteҰཡΛFEͱڞ༗͠·͢ɻ BEଆͰ΋SATͷ૊Έཱͯ࣌ʹར༻͠·͢ɻ

  57. 5 7 SATConverterͰม׵ FE͸ΦϖϨʔλʔʹඥ͍ͮͨSATΛOperatorPolicyAPIͰऔಘ͠ɺݖݶͷͳ͍ػೳ΁ͷಋઢΛඇ ׆ੑԽͨ͠Γ͠·͢ɻ ΤϯυϙΠϯτΛ௥Ճͨ͠ΒRPCͷϓϩόϑͱɺSATConverterΛ͍͡Δඞཁ͕͋ΔͷͰ஫ҙ ʢ͜ͷล͸ࣗಈͰΑ͠ͳʹ͍ͨ͠ɾɾɾ͕ɺ࠷ѱ࿙Εͯ΋BE͸ೝՄΤϥʔʹͳΔͷͰηΩϡϦ ςΟϦεΫʹ͸ͳΒͳ͍ʣ

  58. 5 8 ϑϩϯτଆͷରԠ ͻ·ͷ͕͋γϡοͱ͚ͭΒΕΔΑ͏ʹͯ͘͠Ε͍ͯΔɻ

  59. 5 9 ੍ޚ͍ͨ͠ίϯϙʔωϯτΛ PermissionͰғ͏͚ͩ https://www.notion.so/alpinc/ADR-1667a3385947474e926567413512cf91?p=252d0ed6f3634037b78b704e8ead87ba https://www.notion.so/alpinc/ADR-1667a3385947474e926567413512cf91?p=2c7e0b82c44646feb8f15ba6cc411a0e ৄ͍͠࢖͍ํ͸👇👇👇

  60. 6 0 StorybookͰ΋֬ೝͰ͖ΔΑ͏ʹͳ͍ͬͯΔɻ Allowed/Denied ProviderΛఆٛ͢Δ͚ͩ

  61. 6 1 ࠓޙͷԠ༻

  62. 6 2 ResourceIdϑΟϧλͷޮ཰Խ ݅਺͕ଟ͘ͳΔͱϑΟϧλΛΞϓϦଆͰ΍Δͷ͸͔ͳΓඇޮ཰ͳͷͰɺDao΋EffʹੵΈɺSQL ͷwhere۟ʹresoruceIdΛ࢓ࠐΊΔΑ͏ʹ͍ͨ͠

  63. 6 3 PresenterͷEffԽ PresenterΛEffʹੵΉͱɺPresenterͷॲཧ಺ͰAuthz͕γʔϜϨεʹར༻Ͱ͖ΔΑ͏ʹͳΔͷ Ͱɺͨͱ͑͹ʮಛఆͷ৘ใΛϚεΫ͍ͨ͠ʯͳͲͷཁ݅ʹ΋؆୯ʹରԠͰ͖ΔΑ͏ʹͳΓ· ͢ɻཁ͕݅ग़͖ͯͨΒ΍͍͖͍ͬͯͨɻ

  64. 6 4 ݖݶ؅ཧը໘ ݖݶ؅ཧը໘ɺ݁ߏΉ͍ͣɻϑϩϯτʹ͸ೝՄͷৄࡉΛ఻͑Δඞཁ͕ͳ͍ͷͰSATΛ༻ҙ͠· ͕ͨ͠ɺOperatorʹ͸ࡉ͔͘఻͑Δඞཁ͕͋Δɻ AWSͷIAMΤσΟλΛࢀߟʹ࡞͍͖͍͍͍͍͍ͬͯͨɻʢݱঢ়͸ɺOperator࡞੒࣌ʹͳΜͰ΋Ͱ ͖ΔݖݶΛ෇༩͍ͯ͠Δ + όονͰݖݶ௥ՃͰ͖ΔΑ͏ʹ͍ͯ͠·͢ɻʣ

  65. 6 5 ࠷ޙʹ

  66. 6 6 ·ͩվળͷ༨஍͸͋Δ͕ɺ ͔ͳΓ͍͍ײ͡ʹ࡞Εͨ

  67. 6 7

  68. 6 8 ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠