2015-06-09 13 views
7

Czy istnieje sposób ograniczenia dostępu do/monitorowania adresu URL generowanego przez wtyczkę Java-Melody w Grails przy użyciu ról Shiro?Ograniczenie dostępu do adresu monitorowania monitorowania w języku Java

Aktualizacja: trochę więcej szczegółów. Nie ma problemu, więc zabezpieczyć większość zasobów Grailsa z shiro. Ale w przypadku wtyczki do melodii Java wydaje się, że filtr melodii jest wykonywany przed wykonaniem filtra Shiro. To czyni shiro bezużytecznym.

Istnieje kilka rozwiązań, które mówią, że można to naprawić poprzez zmianę w pliku web.xml, ale nie jest to szybkie działanie, a ja (rdmueller) nie udało się jeszcze sprawić, aby działało. Wtyczka web.xml również wydaje się obiecująca, ale nie chcę dodawać kolejnej wtyczki, aby zabezpieczyć jedną wtyczkę.

Niektóre starsze oświadczenia znajdujące się na stanie internetowej, że ten problem powinien być już rozwiązany poprzez wykorzystanie listy w tym pliku loadAfter: https://github.com/javamelody/grails-melody-plugin/blob/master/GrailsMelodyGrailsPlugin.groovy - ale wydaje się, że to działa tylko dla starszych wersji Grails.

Update2: W celu ułatwienia zaproponować rozwiązanie, mam stworzyć Grails 2.2.4 próbki: https://github.com/rdmueller/SO30739581

prostu sklonować projekt, zrobić grailsw run-app i nawigować do

http://localhost:8080/SO30739581/dbdoc 

, a otrzymasz ekran logowania za pomocą shiro. Przejdź do

http://localhost:8080/SO30739581/monitoring 

a dostaniesz ekran melodii bez logowania :-(

+1

PS:: Shiro-protect-any: 0.1.0-plugin wydaje się działać, ale wydaje być nieco zbyt skomplikowanym, a wtyczka "nie jest w pełni przetestowana". Prostsze rozwiązanie byłoby świetne. – rdmueller

Odpowiedz

3

Zakładam, że używasz Grails 2.x, można go zakodować w ten sposób:

<!-- 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. zaczynając nagrodę, powinienem wyjaśnić problem nieco bardziej szczegółowo: wydaje się, że filtr melodii jest skonfigurowany przed filtrem Shiro, który sprawia, że ​​filtr Shiro jest bezużyteczny. Niemniej jednak, podam twoje rozwiązanie i zobaczę, czy to coś innego niż moje rozwiązanie. – rdmueller

+0

Można zdefiniować zależność od filtru, tak:

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

+0

afaik, filtr melodii znajduje się wewnątrz wtyczki - nieosiągalny z mojego projektu ... – rdmueller

3

skończyło się robi tak, dokonując zmian w web.xml do uwierzytelniania HTTP. Dodaj to do ciebie plik 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> 

Następnie dodać użytkownika i rolę do tomcat-users.xml

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

super - to rozwiązanie działa. Ale nadal będę badał więcej, ponieważ to rozwiązanie a) nie korzysta z shiro b) używa podstawowego uwierzytelniania, co oznacza, że ​​używany jest https - w przeciwnym razie nie będzie on wystarczająco bezpieczny. Niemniej jest to świetne obejście! – rdmueller

+1

btw: Zrobiłem 'grails installTemplates', a następnie dodałem twoją sekcję do pliku web.xml. Wydaje się, że działa całkiem dobrze. Thanx! – rdmueller

+0

Daję nagrodę za tę odpowiedź, ponieważ działa. Nie korzysta z Shiro, ale działa :-) Dziękuję za udostępnienie ... – rdmueller

0

Wystarczy, aby wyświetlić wszystkie dostępne opcje:

shiro-protect-any - plugin wydaje się działać, ale IMHO, wydaje się być nieco zbyt Skomplikowane i wtyczka jest "nie w pełni przetestowana" (mówi autor) ...

0

To nie jest "szybkie trafienie", ale poniższe podejście powinno działać z Shiro lub z jakimikolwiek ramami bezpieczeństwa używanymi przez Twoją grę Grails.

W web.xml, należy dodać następujące elementy powyżej wszelkich istniejących <filter> elementów:

<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> 

ten wezwie com.your.package.MelodyFilter każdym razem wzór /monitoring/* url jest wywoływany.

Następnie należy utworzyć klasę Java MelodyFilter w wersji /src/java/com/your/package/MelodyFilter.java.

W ciele metody doFilter, można wywołać metodę usług Grails wykonywać dowolne kontrole bezpieczeństwa w następujący sposób:

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 { } 
} 

Następnie wystarczy zaimplementować myService.isUserAuthorized() wykonać cokolwiek bezpieczeństwa sprawdza chcesz.

I sprawdzeniu tej techniki pracuje w Grails-2.3.6 z Grails-melodii: 1.59.0

Powiązane problemy