Ограничить доступ к url мониторинга java-melody
есть ли способ ограничить доступ к url-адресу / мониторинга, генерируемому плагином Java-Melody в Grails, используя роли Shiro?
обновление: немного больше деталей. Это не проблема, поэтому обеспечьте большинство ресурсов Grails с shiro. Но в случае плагина Java melody кажется, что фильтр мелодии выполняется до того, как фильтр shiro будет выполнен. Это делает Широ бесполезным.
есть некоторые решения, которые говорят, что это может быть исправлено путем изменения в сети.xml, но это не быстрый хит, и мне (rdmueller) еще не удалось заставить его работать. Сеть.плагин xml также, кажется, обещает некоторую помощь, но я не хочу добавлять другой плагин только для защиты одного плагина.
некоторые старые утверждения, найденные в интернете, утверждают, что эта проблема должна быть уже решена с помощью loadAfter
список в этом файле: https://github.com/javamelody/grails-melody-plugin/blob/master/GrailsMelodyGrailsPlugin.groovy- но похоже, это сработало только для более старых версий Grails.
обновление 2: чтобы было проще предложить решение, я создал образец Grails 2.2.4:https://github.com/rdmueller/SO30739581
просто клонируйте проект, сделайте grailsw run-app
и выберите
http://localhost:8080/SO30739581/dbdoc
и вы получите экран входа в систему через shiro. Выберите
http://localhost:8080/SO30739581/monitoring
и вы получите экран мелодии без входа в систему: - (
4 ответов
Я закончил тем, что внес изменения в web.xml для аутентификации HTTP. Добавить в веб.конфигурационный файл.
<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>
затем добавьте пользователя и роль в tomcat-users.в XML
<user username="yourusername" password="yourpassword" roles="monitoring"/>
Я предполагаю, что вы используете Grails 2.x, вы можете жестко закодировать его таким образом:
<!-- 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')
}
}
}
}
просто перечислить все доступные опции:
на shiro-protect-any-plugin кажется, работает, но IMHO, похоже, слишком сложно, и плагин "не полностью протестирован" (говорит автор)...
это не "быстрый удар", но следующий подход должен работать с Shiro или любой структурой безопасности, которую использует приложение Grails.
в интернете.xml, добавьте следующие элементы над любым существующим <filter>
элементы:
<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>
этой com.your.package.MelodyFilter
в любое время /monitoring/*
вызывается шаблон url.
Далее, вам нужно создать MelodyFilter
Java-класса /src/java/com/your/package/MelodyFilter.java
.
в теле doFilter
метод, вы можете вызвать Grails сервис для выполнения любых необходимых проверок безопасности, следующим образом:
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 { }
}
потом просто реализовать myService.isUserAuthorized()
для выполнения любых проверок безопасности вы хотите.
Я проверил, что эта техника работает в Grails-2.3.6 с grails-melody: 1.59.0