【问题标题】:Using file extension content negotiation with spring security plugin?使用带有弹簧安全插件的文件扩展名内容协商?
【发布时间】:2012-01-21 11:33:10
【问题描述】:

我正在尝试为 grails 使用最新的 spring 安全插件,但遇到了一点问题。

我有一个使用这种方法的控制器:

@Secured(['ROLE_USER'])
def query = {
}

当我点击http://localhost:8080/myApp/myController/query 时,我会收到适当的授权提示。但是,我需要通过文件扩展名进行内容类型协商。使用

grails.mime.file.extensions=true

我可以使用相同的 UrlMappings 并通过 .../myApp/myController/query.js?params=blah 访问我的控制器方法。 但是,没有提示我进行身份验证,并且请求会自动通过或失败,具体取决于我如何设置grails.plugins.springsecurity.rejectIfNoRule

如何通过 spring 安全插件使用文件类型协商?

【问题讨论】:

标签: spring grails groovy annotations spring-security


【解决方案1】:

关闭grails.mime.file.extensions 并添加此过滤器:

class FileExtensionContentNegotiationFilters {
    final static String DEFAULT_FORMAT = "js"
    def filters = {
        all(controller: '*', action: '*') {
            before = {
                addFormatToRequestByFileExtension(request)
            }
            after = {
            }
            afterView = {
            }
        }
    }

    protected addFormatToRequestByFileExtension(def request) {
        String suffix = getSuffixFromPath(request.forwardURI)
        String extension = FilenameUtils.getExtension(suffix)

        if (extension.isEmpty()) {
            request[GrailsApplicationAttributes.CONTENT_FORMAT] = DEFAULT_FORMAT
        }
        else {
            request[GrailsApplicationAttributes.CONTENT_FORMAT] = extension
        }
    }

    protected String getSuffixFromPath(String pathWithoutParams) {
        int lastSlash = pathWithoutParams.lastIndexOf("/")

        if (lastSlash < 0) {
            return ""
        }

        return pathWithoutParams.substring(lastSlash + 1)
    }
}

【讨论】:

    【解决方案2】:

    上面的解决方案并不像预期的那样对我有用。当我请求带有扩展名的 URL 时,会生成 404 响应。

    我提供了另一个不需要关闭grails.mime.file.extensions 并且不需要额外过滤器的解决方案。相反,它是插件类org.codehaus.groovy.grails.plugins.springsecurity.AnnotationFilterInvocationDefinition 的修改。您需要做的是编辑方法determineUrl,如下所示(查看cmets以识别更改):

    @Override
    protected String determineUrl(final FilterInvocation filterInvocation) {
        HttpServletRequest request = filterInvocation.getHttpRequest();
        HttpServletResponse response = filterInvocation.getHttpResponse();
    
        GrailsWebRequest existingRequest = WebUtils.retrieveGrailsWebRequest();
    
        String requestUrl = request.getRequestURI().substring(request.getContextPath().length());
    
        /** The following 2 lines were added */
        int indexOfPeriod = requestUrl.indexOf('.');
        String requestUrlForMatching = (indexOfPeriod != -1) ? requestUrl.substring(0, indexOfPeriod) : requestUrl;
    
        String url = null;
        try {
            GrailsWebRequest grailsRequest = new GrailsWebRequest(request, response,
                    ServletContextHolder.getServletContext());
            WebUtils.storeGrailsWebRequest(grailsRequest);
    
            Map<String, Object> savedParams = copyParams(grailsRequest);
    
            /* Use requestUrlForMatching instead of requestUrl */
            for (UrlMappingInfo mapping : _urlMappingsHolder.matchAll(requestUrlForMatching)) {
                configureMapping(mapping, grailsRequest, savedParams);
    
                url = findGrailsUrl(mapping);
                if (url != null) {
                    break;
                }
            }
        }
        finally {
            if (existingRequest == null) {
                WebUtils.clearGrailsWebRequest();
            }
            else {
                WebUtils.storeGrailsWebRequest(existingRequest);
            }
        }
    
        if (!StringUtils.hasLength(url)) {
            // probably css/js/image
            url = requestUrl;
        }
    
        return lowercaseAndStripQuerystring(url);
    }
    

    问题是带有扩展名的 URL 与使用 UrlMappingsHolder.matchAll 方法的 UrlMappings 中的任何 URL 都不匹配。因此,解决方案是在查找匹配项之前省略扩展名。有了这些更改,一切都按预期工作。

    我还使用https://github.com/grails-plugins/grails-spring-security-core/pull/24 提供的修复创建了一个拉取请求

    您可以在https://github.com/arcesino/grails-spring-security-core/commit/19f87168ec4422b4fe06cc6914adeb1bae4b8752查看更改

    使用版本 1.2.7.3 测试

    【讨论】:

      猜你喜欢
      • 2015-01-31
      • 2011-12-24
      • 2017-07-19
      • 2010-11-26
      • 2012-03-01
      • 1970-01-01
      • 2018-05-08
      • 1970-01-01
      • 2019-02-03
      相关资源
      最近更新 更多