2015-06-09 13 views
7

Esiste un modo per limitare l'accesso/monitoraggio dell'URL generato dal plugin Java-Melody in Grails utilizzando i ruoli di Shiro?Limita l'accesso all'URL di monitoraggio java-melody

Aggiornamento: un po 'più dettagli. Non è un problema quindi proteggere la maggior parte delle risorse Grails con shiro. Ma nel caso del plugin per la melodia java, sembra che il filtro della melodia sia eseguito prima che il filtro shiro venga eseguito. Ciò rende inutile lo shiro.

Ci sono alcune soluzioni che dicono che questo potrebbe essere risolto attraverso una modifica nel web.xml, ma questo non è un colpo rapido e I (rdmueller) non è riuscito a farlo funzionare ancora. Anche il plugin web.xml sembra promettere un po 'di aiuto, ma non voglio aggiungere un altro plugin solo per proteggere un plugin.

Alcune dichiarazioni più anziani trovati sullo stato web che questo problema dovrebbe essere già risolto attraverso l'utilizzo della lista loadAfter in questo file: https://github.com/javamelody/grails-melody-plugin/blob/master/GrailsMelodyGrailsPlugin.groovy - ma sembra che questo ha funzionato solo per le versioni precedenti di Grails.

Update2: Al fine di rendere più facile proporre una soluzione, ho creare un campione Grails 2.2.4: https://github.com/rdmueller/SO30739581

clonare il progetto, fare un grailsw run-app e passare a

http://localhost:8080/SO30739581/dbdoc 

e riceverai una schermata di accesso tramite shiro. Navigare a

http://localhost:8080/SO30739581/monitoring 

e si otterrà la schermata di melodia senza essere collegati :-(

+1

PS: il: shiro-proteggere-any: 0.1.0-plugin sembra funzionare, ma sembra essere un po 'troppo complicato e il plugin è "non completamente testato". Una soluzione più semplice sarebbe grandiosa. – rdmueller

risposta

3

Presumo che si sta utilizzando Grails 2.x, è possibile codificare in questo modo:

<!-- language: java--> 
// grails-app/conf/MonitoringFilters.groovy 
import org.apache.shiro.SecurityUtils 
class MonitoringFilters { 

    def dependsOn = [ShiroSecurityFilters] 

    def filters = { 
     myMonitoringArea(uri: "/monitoring") { 
      before = {  
       SecurityUtils.subject.hasRole('ADMIN')    
      } 
     }  
    } 
} 
+0

OK. con l'avvio della taglia, avrei dovuto spiegare il problema un po 'più in dettaglio: sembra che il filtro della melodia sia configurato prima del filtro shiro che rende inutile il filtro shiro. Tuttavia, darò una soluzione alla tua soluzione e vedrò se è in qualche modo diversa dalla mia soluzione. – rdmueller

+0

È possibile definire la dipendenza del filtro, in questo modo:

 class MonitoringFilters { ... \t def dependsOn = [ShiroSecurityFilters] } 
YeIIowsnow

+0

afaik, il filtro della melodia è all'interno del plug-in - irraggiungibile dal mio progetto ... – rdmueller

3

ho finito per fare in modo da apportare modifiche al web.xml per l'autenticazione HTTP. Aggiungi questo a voi file web.config.

<login-config> 
    <auth-method>BASIC</auth-method> 
    <realm-name>Monitoring</realm-name> 
</login-config> 
<security-role> 
    <role-name>monitoring</role-name> 
</security-role> 
<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>Monitoring</web-resource-name> 
     <url-pattern>/monitoring</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>monitoring</role-name> 
    </auth-constraint> 
</security-constraint> 

quindi aggiungere un utente e il ruolo al vostro tomcat-users.xml

<user username="yourusername" password="yourpassword" roles="monitoring"/> 
+1

ottimo: questa soluzione funziona. Ma esaminerò ancora un po 'di più poiché questa soluzione a) non fa uso di shiro b) usa l'autenticazione di base che implica che https è usato - altrimenti non sarà abbastanza sicuro. Tuttavia è un'ottima soluzione! – rdmueller

+1

btw: Ho fatto un 'grails installTemplates' e poi ho aggiunto la tua sezione al file web.xml. Sembra funzionare abbastanza bene. Grazie! – rdmueller

+0

Io do la generosità a questa risposta poiché funziona. Non fa uso di shiro, ma funziona :-) Grazie per la condivisione ... – rdmueller

0

Solo per elencare tutte le opzioni disponibili:

il shiro-protect-any - plugin sembra funzionare, ma secondo me, sembra essere per essere un po 'troppo complicato e il plugin è "non completamente testato" (dice l'autore) ...

0

Questo non è un "colpo rapido", ma il seguente approccio dovrebbe funzionare con Shiro o qualsiasi altra struttura di sicurezza utilizzata dall'app Grails.

in web.xml, aggiungere i seguenti elementi di sopra di qualsiasi <filter> elementi esistenti:

<filter> 
    <filter-name>melodyFilter</filter-name> 
    <filter-class>com.your.package.MelodyFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>melodyFilter</filter-name> 
    <url-pattern>/monitoring/*</url-pattern> 
</filter-mapping> 

Questo chiamerà com.your.package.MelodyFilter qualsiasi momento il modello /monitoring/* URL viene richiamato.

Successivamente, sarà necessario creare una classe Java MelodyFilter in /src/java/com/your/package/MelodyFilter.java.

Nel corpo del metodo doFilter, si può chiamare un metodo di servizio Grails per eseguire eventuali controlli di sicurezza desiderato, come segue:

package com.your.package; 

import com.my.grails.app.MyService; 
import org.springframework.context.ApplicationContext; 
import org.springframework.web.context.support.WebApplicationContextUtils; 

import javax.servlet.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
import java.io.IOException; 

public class MelodyFilter implements Filter { 

    @Override 
    public void destroy() { } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     String uri = ((HttpServletRequest)request).getRequestURI(); 
     HttpSession session = ((HttpServletRequest)request).getSession(false); 
     ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext()); 
     // replace MyService with your actual service 
     MyService myService = (MyService)ctx.getBean("myService"); 
     // replace isUserAuthorized with your actual service method; 
     // session and uri params included to demonstrate how to pass them 
     // your argument list can be whatever your service method requires 
     boolean authorized = myService.isUserAuthorized(session, uri); 
     if (authorized) { chain.doFilter(request,response); } 
     else { 
      request.setAttribute("error", "User is not authorized to access " + uri); 
      request.getRequestDispatcher("/someController/someAction").forward(request, response); 
     } 
    } 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { } 
} 

Poi basta attuare myService.isUserAuthorized() per eseguire tutti i controlli di sicurezza che desiderate.

Ho verificato questa tecnica funziona in Grails-2.3.6 con graal-melodia: 1.59.0