限制访问java-melody监控url
Posted
技术标签:
【中文标题】限制访问java-melody监控url【英文标题】:Restrict access to java-melody monitoring url 【发布时间】:2015-08-24 17:11:11 【问题描述】:有没有一种方法可以限制对 Grails 中使用 Shiro 角色的 Java-Melody 插件生成的 /monitoring url 的访问?
更新:更多细节。使用 shiro 可以确保大多数 Grails 资源的安全性。但是在 java melody 插件的情况下,似乎在 shiro 过滤器执行之前执行了旋律过滤器。这使得 shiro 无用。
有一些解决方案表示可以通过更改 web.xml 来解决此问题,但这不是一个快速的解决方案,我 (rdmueller) 还没有设法使其工作。 web.xml 插件似乎也能提供一些帮助,但我不想为了保护一个插件而添加另一个插件。
在网络上发现的一些较旧的声明表明,此问题应该已经通过使用此文件中的 loadAfter
列表解决:https://github.com/javamelody/grails-melody-plugin/blob/master/GrailsMelodyGrailsPlugin.groovy - 但似乎这只适用于旧版本的 Grails。
Update2:为了更容易提出解决方案,我创建了一个 Grails 2.2.4 示例:https://github.com/rdmueller/SO30739581
只需克隆项目,执行grailsw run-app
并导航到
http://localhost:8080/SO30739581/dbdoc
然后您将通过 shiro 获得登录屏幕。导航到
http://localhost:8080/SO30739581/monitoring
你会在没有登录的情况下获得旋律屏幕:-(
【问题讨论】:
PS::shiro-protect-any:0.1.0-plugin 似乎可以工作,但它似乎有点过于复杂,并且该插件“未经过全面测试”。一个更简单的解决方案会很棒。 【参考方案1】:我假设您使用的是 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 过滤器之前配置的,这使得 shiro 过滤器无用。不过,我会尝试一下您的解决方案,看看它是否与我的解决方案有所不同。 你可以定义过滤器依赖,像这样:class MonitoringFilters ... def dependsOn = [ShiroSecurityFilters]我最终使用 web.xml 实现了访问控制。我会尝试您的解决方案并再次发表评论。谢谢。 @AverageJoe:你能解释一下你是怎么做到的吗? @rdmueller 我发布了我的解决方案作为问题的更新。【参考方案2】:
我最终通过更改 web.xml 来进行 HTTP 身份验证。将此添加到您的 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>
然后将用户和角色添加到您的 tomcat-users.xml
<user username="yourusername" password="yourpassword" roles="monitoring"/>
【讨论】:
太棒了 - 这个解决方案有效。但是我仍然会进行更多调查,因为这个解决方案 a) 不使用 shiro b) 使用基本身份验证,这意味着使用了 https - 否则它不够安全。尽管如此,这是一个很好的解决方法! 顺便说一句:我做了一个grails installTemplates
,然后将您的部分添加到 web.xml 文件中。似乎工作得很好。谢谢!
我为这个答案提供了赏金,因为它有效。它不使用 shiro,但它可以工作 :-) 感谢分享...【参考方案3】:
仅列出所有可用选项:
shiro-protect-any - plugin 似乎可以工作,但恕我直言,它似乎有点太复杂了,并且插件“没有完全测试”(作者说)......
【讨论】:
【参考方案4】:这不是“速成”,但以下方法应该适用于 Shiro 或您的 Grails 应用程序使用的任何安全框架。
在 web.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>
这将在任何时候调用/monitoring/*
url 模式时调用com.your.package.MelodyFilter
。
接下来,您需要在/src/java/com/your/package/MelodyFilter.java
中创建一个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-melody:1.59.0 验证了这种技术在 Grails-2.3.6 中有效
【讨论】:
以上是关于限制访问java-melody监控url的主要内容,如果未能解决你的问题,请参考以下文章