Extension de services d’autorisation (existante)
Les extensions de services permettent une flexibilité totale dans le processus de contrôle d’accès aux ressources protégées.
Comment les passerelles d’applications gèrent le trafic
Un peu de contexte est nécessaire à la compréhension du fonctionnement du processus d’autorisation et de sa place dans le flux d’identité d’un utilisateur. Voici comment le trafic circule dans une AppGateway (en pseudocode).
func Serve(appGateway *app.AppGateway, rw http.ResponseWriter, req *http.Request) {
if !isAuthenticated(){
Authenticate(resp, req)
}
LoadAttrs()
if IsAuthorized() {
SetHeaders()
Proxy()
}
}
Il s’agit d’une simplification. La mise en œuvre effective met en cache les informations relatives à la session par souci d’efficacité, y compris les résultats de la vérification de l’authentification et de l’autorisation. Ainsi, ces méthodes ne sont généralement pas sollicitées pour chaque requête, mais uniquement lors du premier passage de l’utilisateur.
Autorisation
Comme le montre le pseudocode ci-dessus, l’autorisation intervient une fois que l’identité de l’utilisateur a été établie par le biais de l’authentification et que les attributs de l’utilisateur ont été chargés. Le processus d’autorisation est ensuite appliqué pour contrôler l’accès à la ressource demandée.
AuthN ou AuthZ
L’authentification (AuthN) sert simplement à confirmer l’identité de l’utilisateur, et non à déterminer s’il dispose d’un accès. Un utilisateur peut être authentifié, mais se voir refuser l’accès au stade de l’autorisation (AuthZ).
Extension de services IsAuthorized
Cette extension de services renvoie une valeur booléenne indiquant si l’accès est autorisé ou refusé. En règle générale, elle applique sa logique sur la base des attributs déjà disponibles dans la session de l’utilisateur (par exemple, ceux chargés lors de la phase LoadAttrsSE
), ou sur la base des propriétés intrinsèques de la requête.
http.ResponseWriter
, elle n’envoie généralement
pas de réponse directement à l’utilisateur. L’écriture dans le
corps ou les en-têtes de http.ResponseWriter
peut entraîner un comportement indésirable.Voici un exemple de l’extension de services isAuthorizedSE
mise en œuvre à la fois au niveau de
l’AppGateway et de l’emplacement.
appgateways:
- name: alpha
# ...
isAuthorizedSE:
funcName: DefaultIsAuthorized
file: /etc/maverics/extensions/alpha/auth.go
policies:
- location: /
authentication:
idps:
- azure
- location: /admin
authentication:
idps:
- azure
authorization:
isAuthorizedSE:
funcName: AdminIsAuthorized
file: /etc/maverics/extensions/alpha/auth.go
/etc/maverics/extensions/alpha/auth.go
package main
import (
"net/http"
"strings"
"maverics/app"
"maverics/log"
"maverics/session"
)
// DefaultIsAuthorized ensures the user is a Canary Bank staffer.
func DefaultIsAuthorized(ag *app.AppGateway, rw http.ResponseWriter, req *http.Request) bool {
log.Debug(
"msg", "determining if user is authorized",
"extension", "DefaultIsAuthorized",
)
if isCanaryStaffer(req) {
return true
}
return false
}
// AdminIsAuthorized ensures the user is a Canary Bank staffer and that they
// work in the accounting department.
func AdminIsAuthorized(ag *app.AppGateway, rw http.ResponseWriter, req *http.Request) bool {
log.Debug(
"msg", "determining if user is authorized",
"extension", "AdminIsAuthorized",
)
if isCanaryStaffer(req) && isAdmin(req) {
return true
}
return false
}
func isCanaryStaffer(req *http.Request) bool {
email := session.GetString(req, "azure.email")
return strings.HasSuffix(email, "@canarybank.io")
}
func isAdmin(req *http.Request) bool {
department := session.GetString(req, "ldap.department")
return department == "Accounting"
}