7

有没有办法可以使用 Shiro 角色限制对 Grails 中 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

并且您无需登录即可获得旋律屏幕:-(

4

4 回答 4

5

我最终通过更改 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"/>
于 2015-07-19T00:56:26.467 回答
3

我假设您使用的是 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')             
           }
        }       
    }
}
于 2015-07-15T15:01:05.783 回答
1

这不是“速成”,但以下方法应该适用于 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>

这将com.your.package.MelodyFilter在任何时候/monitoring/*调用 url 模式时调用。

接下来,您需要MelodyFilter/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-melody:1.59.0 验证了这种技术在 Grails-2.3.6 中有效

于 2017-04-11T21:58:32.630 回答
0

仅列出所有可用选项:

shiro-protect-any - 插件似乎工作,但恕我直言,它似乎有点太复杂了,插件“没有完全测试”(作者说)......

于 2015-07-19T17:58:50.283 回答