Adding @With(Secure.class)
to a controller blocks all unauthenticated access. Is there a way to enabled it only for certain actions, or to except certain actions after it's enabled on a controller?
问题:
回答1:
You can't do that with the secure module. As Niels said the secure module is more an example than a solution. You can build your own security system with the @Before annotation. Here is an example:
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
}
I recommend you to read the source code of the secure module.
回答2:
I've since found my earlier @Public
solution somewhat limiting since it can't address inherited actions. I've instead gone to a class-level annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AllowGuest {
String[] value();
}
and added this code to the beginning of the Secure.checkAccess()
method:
AllowGuest guest = getControllerInheritedAnnotation(AllowGuest.class);
if (guest != null) {
for (String action : guest.value()) {
if (action.equals(request.actionMethod))
return;
}
}
which can be used like this: @AllowGuest({"list","view"})
This makes it easy to allow access to local and inherited actions, and to see which actions in a controller are unsecured.
回答3:
Remove @With(Secure.class)
annotation to the controller and add this piece of code inside the controller.
@Before(unless={"show"})
static void checkAccess() throws Throwable {
Secure.checkAccess();
}
where show
is the action you need to make publicly available.
回答4:
In order to get what I was looking for, I copied the Check
annotation and created a Public
annotation.
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 {
}
then I added these two lines to the beginning of the Secure.checkAccess
:
if (getActionAnnotation(Public.class) != null)
return;
Now actions in controllers using With(Secure.class)
can be made accessible without logging in by adding a @Public
annotation to them.
回答5:
You can set at the @Before-Tag of the Secure Controller the value unless or only. The Secure-Module is more an example than a solution.