【问题标题】:Restrict access to java-melody monitoring url限制访问java-melody监控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 似乎可以工作,但它似乎有点过于复杂,并且该插件“未经过全面测试”。一个更简单的解决方案会很棒。

标签: grails shiro java-melody


【解决方案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 中,在任何现有的 &lt;filter&gt; 元素上方添加以下元素:

    <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 中有效

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-16
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多