Come non divulgare le informazioni di controllo al livello aziendale

0

Da un'API REST, scriviamo al database. Vogliamo memorizzare chi era la persona che ha attivato questo cambiamento. Abbiamo queste informazioni a livello di controller. Il salvataggio avviene a livello di repository (Utilizziamo spring boot e abbiamo un livello di servizio intermedio per la business logic).

Come posso interrompere la divulgazione delle informazioni di controllo al livello aziendale? Se si passa l'utente dal controller al repository, ogni metodo dovrà prendere l'utente, direttamente o spostato in un altro oggetto.

C'è un modo per evitarlo? Forse specificamente con Spring?

    
posta Can't Tell 22.02.2018 - 14:49
fonte

2 risposte

1

Anche se sono d'accordo che l'auditing può essere parte del livello aziendale, è facile modificare la domanda per evitare questa ambiguità.

Ad esempio, si sta registrando i tempi di risposta dal server in modo da poter rilevare se alcuni sono sovraccarichi. Ciò potrebbe anche colpire un database, ma diverso rispetto alla logica aziendale.

La soluzione consiste semplicemente nell'avere un repository diverso e nell'aggiungere un livello di servizio che incapsula la logica aziendale, separandola dal livello di hosting.

Questo è utile anche quando hai altre cose che devi fare, ma che non fanno parte della logica aziendale.

public class MyController
{
    MyController(IServiceLayer service, ILogger logger)
    {
       ...
    }

    public myThing GetThing(string id)
    {
        //the rest service needs to log how many times its called
        logger.log(user, metric);

        //this service could be hosted anywhere, it doesn't care
        var thing = service.GetThing(id);

        //the rest service needs to return json and http error codes, 
        //not objects and exceptions
        var httpReturn = new HttpReturnObject(200, Json.Serialise(thing));
        return httpReturn;
    }
}
    
risposta data 22.02.2018 - 16:09
fonte
1

Quando costruisci un api per il riposo di primavera, puoi incorporare Spring Security. È possibile configurarlo in modo tale che una rappresentazione dell'utente (ad esempio presa da un token al portatore nell'intestazione Authorization delle richieste) sia memorizzata nel contesto di sicurezza Spring, che può quindi essere recuperato nel livello dati chiamando qualcosa come:

MyUserDetails getUserFromSecurityContext(){
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication == null || !authentication.isAuthenticated()) {
      return null;
    }
    return ((MyUserDetails) authentication.getPrincipal()).getUser();
}

In effetti il tuo livello aziendale potrebbe / dovrebbe fare anche questo (*), ma non necessariamente così. Il "trucco" qui sta usando il SecurityContextHolder statico, aggirando così il livello di servizio in modo che non sia necessario passare l'utente come argomento attraverso tutti i livelli intermedi, poiché è implicitamente disponibile nel SecurityContextHolder statico.

(*) È possibile utilizzare l'utente autenticato nel decidere se l'utente ha accesso a un metodo di servizio oppure no, ad esempio configurando methodecurity

    
risposta data 10.12.2018 - 15:48
fonte

Leggi altre domande sui tag