将@With(Secure.class)
添加到控制器会阻止所有未经身份验证的访问。有没有办法只为某些操作启用它,或者在控制器上启用某些操作后除外?
答案 0 :(得分:9)
您无法使用安全模块执行此操作。正如Niels所说,安全模块不仅仅是一个解决方案。您可以使用@Before注释构建自己的安全系统。这是一个例子:
public class Admin extends Controller {
@Before(unless={"login", "authenticate", "logout", "otherMethod"})
void checkAccess() {
// check the cookie
}
public void login() {
render();
}
public void authenticate(String email, String password) {
// check the params and set a value in the cookie
}
public void logout() {
// delete cookie
}
我建议您阅读安全模块的源代码。
答案 1 :(得分:4)
我发现我之前的@Public
解决方案有些限制,因为它无法解决继承的操作。我转而使用类级注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AllowGuest {
String[] value();
}
并将此代码添加到Secure.checkAccess()
方法的开头:
AllowGuest guest = getControllerInheritedAnnotation(AllowGuest.class);
if (guest != null) {
for (String action : guest.value()) {
if (action.equals(request.actionMethod))
return;
}
}
可以这样使用:@AllowGuest({"list","view"})
这样可以轻松访问本地和继承的操作,并查看控制器中的哪些操作是不安全的。
答案 2 :(得分:2)
删除@With(Secure.class)
注释到控制器并在控制器中添加这段代码。
@Before(unless={"show"})
static void checkAccess() throws Throwable {
Secure.checkAccess();
}
其中show
是您需要公开发布的操作。
答案 3 :(得分:1)
为了获得我想要的内容,我复制了Check
注释并创建了Public
注释。
package controllers;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Public {
}
然后我将这两行添加到Secure.checkAccess
的开头:
if (getActionAnnotation(Public.class) != null)
return;
现在可以使用With(Secure.class)
访问控制器中的操作,而无需通过向其添加@Public
注释来登录。
答案 4 :(得分:0)
您可以在安全控制器的@ Before-Tag中设置值,除非或仅。安全模块不仅仅是一个解决方案。