2015-06-09 18 views
7

Có cách nào để hạn chế quyền truy cập vào/giám sát url được tạo bởi plugin Java-Melody trong Grails bằng vai trò Shiro không?Hạn chế quyền truy cập vào url theo dõi giai điệu java

Cập nhật: chi tiết hơn một chút. Không có vấn đề gì an toàn cho hầu hết Grails ressources với shiro. Nhưng trong trường hợp plugin java melody, có vẻ như bộ lọc giai điệu được thực hiện trước khi bộ lọc shiro được thực thi. Điều này làm cho Shiro vô dụng.

Có một số giải pháp cho rằng điều này có thể được khắc phục thông qua thay đổi trong tệp web.xml, nhưng đây không phải là lần truy cập nhanh và tôi (rdmueller) đã không quản lý để làm cho nó hoạt động. Plugin web.xml cũng có vẻ hứa hẹn một số trợ giúp, nhưng tôi không muốn thêm một plugin khác chỉ để bảo mật một plugin.

Một số câu lệnh cũ được tìm thấy trên trạng thái web rằng sự cố này đã được giải quyết thông qua việc sử dụng danh sách loadAfter trong tệp này: https://github.com/javamelody/grails-melody-plugin/blob/master/GrailsMelodyGrailsPlugin.groovy - nhưng có vẻ như điều này chỉ hoạt động đối với các phiên bản cũ hơn của Grails.

Update2: Để làm cho nó dễ dàng hơn để đưa ra một giải pháp, tôi đã tạo ra một mẫu Grails 2.2.4: https://github.com/rdmueller/SO30739581

chỉ cần sao chép dự án, làm một grailsw run-app và điều hướng đến

http://localhost:8080/SO30739581/dbdoc 

và bạn sẽ nhận được màn hình đăng nhập qua shiro. Điều hướng đến

http://localhost:8080/SO30739581/monitoring 

và bạn sẽ nhận được màn hình giai điệu mà không bị đăng nhập :-(

+1

PS:: shiro-protect-bất kỳ: 0.1.0-Plugin dường như làm việc, nhưng nó có vẻ trở nên quá phức tạp và plugin "chưa được kiểm tra đầy đủ". Một giải pháp đơn giản sẽ là tuyệt vời. – rdmueller

Trả lời

3

Tôi giả sử bạn đang sử dụng Grails 2.x, bạn có thể hardcode nó theo cách này:

<!-- 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. với việc bắt đầu tiền thưởng, tôi nên giải thích vấn đề chi tiết hơn một chút: có vẻ như bộ lọc giai điệu được cấu hình trước bộ lọc shiro làm cho bộ lọc shiro vô dụng. Tuy nhiên, tôi sẽ cung cấp cho giải pháp của bạn một thử và xem nếu nó là bằng cách nào đó khác với giải pháp của tôi. – rdmueller

+0

Bạn có thể xác định phụ thuộc bộ lọc, như sau:

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

+0

afaik, bộ lọc giai điệu nằm trong plugin - không truy cập được từ dự án của tôi ... – rdmueller

3

tôi đã kết thúc làm như vậy bằng cách thay đổi web.xml để xác thực HTTP. Thêm này cho bạn file 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> 

Sau đó, thêm một người dùng và vai trò để tomcat-users.xml bạn

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

tuyệt vời - giải pháp này hoạt động. Nhưng tôi vẫn sẽ điều tra thêm một chút vì giải pháp này a) không sử dụng shiro b) sử dụng auth cơ bản ngụ ý rằng https được sử dụng - nếu không nó sẽ không đủ an toàn. Tuy nhiên đó là một giải pháp tuyệt vời! – rdmueller

+1

btw: Tôi đã thực hiện 'grails installTemplates' và sau đó thêm phần của bạn vào tệp web.xml. Dường như làm việc khá tốt. Thanx! – rdmueller

+0

Tôi trả tiền thưởng cho câu trả lời này vì nó hoạt động. Nó không sử dụng shiro, nhưng nó hoạt động :-) Thanx để chia sẻ ... – rdmueller

0

Chỉ cần liệt kê tất cả tùy chọn có sẵn:

các shiro-protect-any - plugin dường như làm việc, nhưng IMHO, nó có vẻ là có một chút quá phức tạp và plugin là "chưa được kiểm tra đầy đủ" (tác giả) ...

0

Đây không phải là "nhấn nhanh", nhưng cách tiếp cận sau đây sẽ làm việc với Shiro hoặc bất kỳ khung bảo mật nào mà ứng dụng Grails của bạn sử dụng.

Trong web.xml, thêm các yếu tố sau trên bất kỳ <filter> yếu tố hiện có:

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

này sẽ gọi com.your.package.MelodyFilter bất kỳ thời gian mô hình /monitoring/* url được gọi.

Tiếp theo, bạn sẽ cần phải tạo một lớp học MelodyFilter Java trong /src/java/com/your/package/MelodyFilter.java.

Trong phần thân của phương pháp doFilter, bạn có thể gọi một phương thức dịch vụ Grails để thực hiện bất kỳ kiểm tra an ninh mong muốn, như sau:

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

Sau đó chỉ cần thực hiện myService.isUserAuthorized() để thực hiện bất cứ điều gì kiểm tra an ninh mà bạn mong muốn.

Tôi đã xác minh kỹ thuật này làm việc trong Grails-2.3.6 với grails-giai điệu: 1.59.0

Các vấn đề liên quan