URL
Attention
https://bit.ly/devio2019-authz
#cmdevio #cmdevio2
✦
✦
✦
✦ 

✦
✦
✦ 

✦
✦ 

Twitter @daisuke_m
#cmdevio #cmdevio2






















#cmdevio #cmdevio2








#cmdevio #cmdevio2
API
UI
#cmdevio #cmdevio2
✦
✦
✦
✦
✦
✦
✦
total
45 min
#cmdevio #cmdevio2


4 

ADI, ADF

#cmdevio #cmdevio2
#cmdevio #cmdevio2








#cmdevio #cmdevio2
✦
✦
✦ 

#cmdevio #cmdevio2


4 

ADI, ADF

#cmdevio #cmdevio2
























※ 

( )
#cmdevio #cmdevio2



 @PreAuthorize @PostAuthorize



 @PreFilter @PostFilter
※ 

Java Spring Security
#cmdevio #cmdevio2


4 

ADI, ADF

#cmdevio #cmdevio2
¥20,856




#cmdevio #cmdevio2
✦ 

adf: (adi) ↦ allow/deny (boolean)
✦ 

✦
✦ 

#cmdevio #cmdevio2
✦
✦
✦
✦
✦
✦
#cmdevio #cmdevio2
✦ Referer
✦
✦
✦
✦
✦
#cmdevio #cmdevio2
#cmdevio #cmdevio2
✦ 

✦
✦
✦
✦
✦
#cmdevio #cmdevio2


4 

ADI, ADF

#cmdevio #cmdevio2
✦
✦
✦
✦
✦
✦
#cmdevio #cmdevio2












emps.create({

"id": "ezaki"

});
POST /emps



{

"id": "ezaki"

}
#cmdevio #cmdevio2
✦
#cmdevio #cmdevio2
✦
✦ CreateEmp ListEmp GetEmp
UpdateEmp DeleteEmp
✦
✦
✦
✦
AWS
#cmdevio #cmdevio2
✦ 

adf: (adi) ↦ allow/deny (boolean)
@RequestMapping

fun getEmp(param: Any, adi: AccessDicisionInfo) {
if (adf(adi) == false) {
throw AccessDeniedException()
}
val resource = service.getEmp(param)
return Response.ok(resource)
}
#cmdevio #cmdevio2
ADI 



adf 

#cmdevio #cmdevio2
✦
✦ 

✦ adi.action
#cmdevio #cmdevio2
adi.sub.authorities
✦
{
"name": "ezaki",
"authorities": [
"ListEmp",
"GetEmp",
"UpdateEmp",
"UpdateEmpByAdmin"
]
}
{
"name": "takada",
"authorities": [
"ListEmp",
"UpdateEmp"
]
}
fun adf(adi: AccessDecisionInfo) {
return adi.sub.authorities.contains(adi.action)
}
#cmdevio #cmdevio2
✦
✦ UpdateEmp
UpdateEmp("kaga", {
"name": " "
})
UpdateEmp("kaga", {
"salary": 888888
})
by kaga by kaga
200 OK 403 Forbidden
#cmdevio #cmdevio2
✦
✦ UpdateEmp

✦ UpdateEmpByAdmin

✦ 

#cmdevio #cmdevio2
✦
✦
UpdateEmpByAdmin("kaga", {
"salary": 888888
})
UpdateEmp("kaga", {
"name": " "
})
UpdateEmpByAdmin UpdateEmp
200 OK (by ezaki) 200 OK (by kaga)

( API )403 Forbidden (by takada)
#cmdevio #cmdevio2
✦
✦ adi.action
✦ adi.sub.authorities
✦ adf
✦ adi.action adi.sub.authorities
✦ contains
#cmdevio #cmdevio2


#cmdevio #cmdevio2






#cmdevio #cmdevio2
postFilter
✦
✦ GetEmp
{
"id": "kaga",
"address": "...",
"name": "Kaga Masaru",
"tel": "090-0000-0006",
"salary": 999999,
"dept": 2
}
{
"id": "kaga",
"name": "Kaga Masaru",
"tel": "090-0000-0006",
"dept": 2
}
by ezaki by takada
#cmdevio #cmdevio2
✦
✦
✦
GetEmpByAdmin GetEmp
{
"id": "kaga",
"address": "...",
"name": "Kaga Masaru",
"tel": "090-0000-0006",
"salary": 999999,
"dept": 2
}
{
"id": "kaga",
"name": "Kaga Masaru",
"tel": "090-0000-0006",
"dept": 2
}
#cmdevio #cmdevio2
✦ 

✦
✦ ListEmp
✦
✦ ListEmp ListEmpForPartner
✦ ListEmp ListEmpForPartner
#cmdevio #cmdevio2
✦ 

✦
✦
✦
✦
✦
✦
✦
#cmdevio #cmdevio2
#cmdevio #cmdevio2
✦
✦ ezaki UpdateEmp("ezaki", p) name 

✦ ezaki UpdateEmp("kanou", p) name 

✦
✦ 

UpdateEmp
#cmdevio #cmdevio2
✦ 

/emps/ezaki
✦
✦ adi.obj.owner
✦ adi.sub.name adi.obj.owner
✦ adi.obj.owner
#cmdevio #cmdevio2
✦
{
"id": "ezaki",

"owner": "ezaki",
// ...
}
{
"id": "kanou",
"owner": "kanou",
// ...
}
fun adf(adi: AccessDecisionInfo) {
return adi.sub.name == adi.obj.owner
}
#cmdevio #cmdevio2
✦
✦ ezaki UpdateEmp("kaga", p) name 

✦ ezaki UpdateEmp("ushijima", p) name 

✦
✦ 

#cmdevio #cmdevio2
✦
✦ authorities
✦
✦
#cmdevio #cmdevio2
✦
{
"id": "kaga",

"acl": [
{ ezaki
UpdateEmp }
],
// ...
}
{
"id": "ushijima",
"acl": [],
// ...
}
fun adf(adi: AccessDecisionInfo) {
return adi.obj.acl.allow(adi.sub, adi.action)
}
#cmdevio #cmdevio2
✦ { ezaki UpdateEmp }
✦
{
"effect": "allow",
"action": "UpdateEmp",
"authority": "Leader"
}
{
"name": "ezaki",
"authorities": [
"Leader",
// ...
]
}
obj ADI ( ) sub ADI
#cmdevio #cmdevio2
✦
✦
✦ adf
✦
✦ adi.action
✦ adi.sub.name
✦ adi.sub.authorities
✦ adi.obj.owner
✦ adi.obj.acl
✦
#cmdevio #cmdevio2




https://classmethod.jp/recruit/
https://prismatix.jp/recruit/
認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio

認証の標準的な方法は分かった。では認可はどう管理するんだい? #cmdevio