我正在尝试使用最新的Spring安全插件来获取grails,但是我遇到了一点点。
我有一个使用此方法的控制器:
@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 security plugin进行文件类型协商?
答案 0 :(得分:0)
关闭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)
}
}
答案 1 :(得分:-1)
上述解决方案对我不起作用。当我请求带扩展名的网址时,会生成404响应。
我提供了另一种解决方案,无需关闭grails.mime.file.extensions
,也不需要额外的过滤器。相反,它是对插件类org.codehaus.groovy.grails.plugins.springsecurity.AnnotationFilterInvocationDefinition
的修改。您需要做的是编辑方法determineUrl
,如下所示(查看注释以确定更改):
@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);
}
问题是,带有扩展名的网址与使用UrlMappings
方法的UrlMappingsHolder.matchAll
中的任何网址都不匹配。因此,解决方案是在查找匹配之前省略扩展。通过此更改,一切都按预期工作。
我还创建了一个拉取请求,其中包含https://github.com/grails-plugins/grails-spring-security-core/pull/24
处的修复程序 看到更改使用1.2.7.3版本进行测试