Воспроизвести фреймворк: как требовать входа в систему для некоторых действий, но не все

StackOverflow https://stackoverflow.com/questions/4328455

Вопрос

Добавление @With(Secure.class) Для контроллера блокирует весь неавентицированный доступ. Есть ли способ включить его только для определенных действий или, кроме определенных действий после того, как он включен на контроллер?

Это было полезно?

Решение

Вы не можете сделать это с безопасным модулем. Как сказал Нильс, защищенный модуль является скорее примером, чем решением. Вы можете построить свою собственную систему безопасности с аннотацией @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
}

Я рекомендую вам прочитать исходный код защищенного модуля.

Другие советы

С тех пор я нашел свое раннее @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"})

Это позволяет легко допустить доступ к локальным и унаследованным действиям и посмотреть, какие действия в контроллере не являются безопасными.

Удалять @With(Secure.class) Аннотация контроллеру и добавьте этот кусок кода в контроллер.

@Before(unless={"show"})
static void checkAccess() throws Throwable {
    Secure.checkAccess();
}

куда show это действие, которое вам нужно, чтобы сделать общедоступную.

Чтобы получить то, что я искал, я скопировал 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 аннотация им.

Вы можете установить на @перед тематическим контроллером значения или только. Безопасный модуль является скорее примером, чем решением.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top