Aggiunta del livello di sicurezza per più servizi

1

La mia applicazione web al momento accetta richieste REST e gestite tramite alcuni controller, che chiamano i servizi corrispondenti per eseguire la logica.

Ora voglio aggiungere alcune regole di sicurezza prima di chiamare i servizi. Ciò include la verifica della possibilità di accedere a un servizio ANCHE modificare il corpo della richiesta, se necessario. Ho difficoltà a decidere dove e come aggiungere questo livello di sicurezza.

La soluzione 1 consiste nel creare versioni sicure per ciascuno dei servizi, avvolgere il servizio originale e sostituirli in ciascuno dei controller. Esporre solo i servizi protetti e rendere i servizi originali privati / pacchetti protetti. In questo modo tutti i miei servizi rimangono separati nei propri moduli e la sicurezza viene applicata. Ma posso anche solo aggiornare i servizi, senza avere un ulteriore livello?

La soluzione 2 è quella di creare un singolo servizio di sicurezza e prende le richieste di servizio dai controllori, esegue i controlli di sicurezza, modifica il corpo della richiesta, quindi invia le richieste aggiornate ai servizi corrispondenti. In questo modo posso avere solo un modulo di sicurezza e la sicurezza è applicata, ma questo modulo deve conoscere ognuno dei servizi per inviare i servizi corretti.

La soluzione 3 consiste nel creare un singolo servizio di sicurezza e lasciare che i controllori corrispondenti lo usino a proprio piacimento. In altre parole, il singolo controller gestisce parte della logica di sicurezza. per esempio. un controllore chiama il controllo di sicurezza, quindi passa nel corpo della richiesta per ottenere la richiesta modificata prima di chiamare il servizio. In questo modo posso avere solo un modulo di sicurezza e questo modulo non ha bisogno di conoscere ognuno dei servizi, ma non sta proteggendo alcun servizio e agisce proprio come una classe di utilità. Ad esempio, non vi è alcun obbligo per il nuovo controllore di passare attraverso questa logica di sicurezza.

Esiste una soluzione in grado di rafforzare la sicurezza, rimanere nel proprio modulo e nessuna dipendenza dai servizi esistenti?

    
posta user1589188 06.11.2018 - 07:36
fonte

1 risposta

2

Usa un filtro (pattern dell'intercettore) e aggiungi una classe SecurityFilter al tuo Servlet ... Ci sono un sacco di esempi là fuori ... Ti darò uno dei miei:

    import java.io.IOException;
    import java.util.Map;

    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;

    import com.turnmarker.next.models.DistributedSessionModel;
    import com.turnmarker.next.models.PayloadModel;

    @Component
    @Order(0)
    public class AuthenticationFilterBean extends AbstractBean implements Filter {

        /**
         * 
         */
        private static final long serialVersionUID = 8592924875474194043L;

        @SuppressWarnings("unused")
        private FilterConfig fc;

        // TODO: CHANGE THIS SO THAT SESSION's ARE STORED/RETRIEVED FROM A DISTRIBUTED-SESSION-MAP:
        @Autowired
        private DistributedSessionModel dsm; // = DistributedSessionModel.getInstance();

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

            // CAST INTO SOMETHING WE CAN MANIPULATE:
            HttpServletRequest req = (HttpServletRequest) request;
            Map<String, String[]> params = request.getParameterMap();

            // SESSION's ARE STORED/RETRIEVED FROM THE DISTRIBUTED-SESSION-MAP:
            HttpSession session = req.getSession(false);

            if ((null != session) && (dsm.contains(session.getId()))) {

                getLogger().warn("I found your session: " + session.getId());

                if (params.get("TURN") == null) {

                    trace("AuthenticationFilterBean::doFilter() --> HttpServletRequest is missing a required parameter.");

                    // JUST GO-AWAY:
                    response.reset();
                    // response.getOutputStream().close();

                    // INSTANTIATE:
                    HttpServletResponse res = (HttpServletResponse) response;

                    // CONFIGURE:
                    // res.setContentType("application/json");
                    res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request");

                    // GOODBYE, CRUEL WORLD:
                    res.getOutputStream().flush();

                    // AND CLOSE:
                    res.getOutputStream().close();

                    // AND RETURN:
                    return;

                } else {

                    trace("AuthenticationFilterBean::doFilter() --> Required parameter located on HttpServletRequest.");

                }

            }

            // OTHERWISE:
            chain.doFilter(request, response);

        }

        @Override
        public void destroy() {

            trace("AuthenticationFilterBean::destroy() --> Method called");

        }

        @Override
        public void init(FilterConfig conf) throws ServletException {

            trace("AuthenticationFilterBean::init() --> Method called");

            // STORE:
            this.fc = conf;

        }

        // LOGGER IMPLEMENTATION:
        protected Logger logger = LoggerFactory.getLogger(PayloadModel.class);

        protected Logger getLogger() {

            return logger;

        }

        protected void setLogger(Logger logger) {

            this.logger = logger;

        }

    }
    
risposta data 06.11.2018 - 20:23
fonte

Leggi altre domande sui tag