Keycloak - атрибуты пользователя только для чтения - PullRequest
0 голосов
/ 07 мая 2020

Я хочу сохранить некоторую информацию в Keycloak как настраиваемые атрибуты пользователя.

Некоторые из них должны управляться самим пользователем. Остальные атрибуты должны управляться только администратором Keycloak. Атрибуты, управляемые администратором, должны быть доступны только для чтения на веб-странице «Редактировать учетную запись» для пользователя.

Я просмотрел руководство , чтобы добавить настраиваемые атрибуты пользователя на эту страницу и настроить веб-страницу «Редактировать учетную запись».

Мой вопрос: Гарантировано ли, что пользователь не может изменить атрибут, который предназначен для пользователя только для чтения? Например, отправив форму, в которой он / она отправляет правильные данные, которые будут автоматически сопоставлены на стороне сервера с атрибутом пользователя.

1 Ответ

0 голосов
/ 07 мая 2020

Судя по тому, что вы сказали, у вас есть три варианта.

Один - сохранить страницу Keycloak «Редактировать учетную запись» и использовать прослушиватель профиля обновления , чтобы проверить, какие атрибуты сохраняются или какие обновляются кем, что-то вроде этого:

public class UpdateProfile implements RequiredActionProvider, RequiredActionFactory, DisplayTypeRequiredActionFactory {
    @Override
    public InitiatedActionSupport initiatedActionSupport() {
        return InitiatedActionSupport.SUPPORTED;
    }

    @Override
    public void evaluateTriggers(RequiredActionContext context) {
    }

    @Override
    public void requiredActionChallenge(RequiredActionContext context) {
        Response challenge = context.form()
                .createResponse(UserModel.RequiredAction.UPDATE_PROFILE);
        context.challenge(challenge);
    }

    // Check the custom attribute 1 not being modified by the user
    @Override
    public void processAction(RequiredActionContext context) {
        EventBuilder event = context.getEvent();
        event.event(EventType.UPDATE_PROFILE);
        MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
        UserModel user = context.getUser();
        KeycloakSession session = context.getSession();
        RealmModel realm = context.getRealm();

        String newYourCustomAttribute1 = formData.getFirst("yourCustomAttribute1");
        String oldYourCustomAttribute1 = user.getFirstAttribute("yourCustomAttribute1") 

        if (!newYourCustomAttribute1.equals(oldYourCustomAttribute1)) {
            Response challenge = context.form()
                    .setError("User cannot change the attribute")
                    .setFormData(formData)
                    .createResponse(UserModel.RequiredAction.UPDATE_PROFILE);
            context.challenge(challenge);
            return;
        }
        context.success();

    }


    @Override
    public void close() {

    }

    @Override
    public RequiredActionProvider create(KeycloakSession session) {
        return this;
    }


    @Override
    public RequiredActionProvider createDisplay(KeycloakSession session, String displayType) {
        if (displayType == null) return this;
        if (!OAuth2Constants.DISPLAY_CONSOLE.equalsIgnoreCase(displayType)) return null;
        return ConsoleUpdateProfile.SINGLETON;
    }



    @Override
    public void init(Config.Scope config) {

    }

    @Override
    public void postInit(KeycloakSessionFactory factory) {

    }

    @Override
    public String getDisplayText() {
        return "Update Profile";
    }


    @Override
    public String getId() {
        return UserModel.RequiredAction.UPDATE_PROFILE.name();
    }
}

Я не знаю, будет ли вызываться этот слушатель, когда вы также обновляете профиль из своего клиентского приложения. Если он будет вызван, вам нужно будет проверить, какой клиент вошел в систему, если это клиент publi c, не позволяйте обновлять атрибуты, если это ваш клиент службы, позвольте ему.

Второй будет только позволить вашему сервисному клиенту обновлять профили пользователей и создавать настраиваемое представление в вашем приложении, которое отправляет POST формы вашему клиенту, а не напрямую keycloak. Таким образом, вы можете проверить его в службе перед отправкой в ​​keycloak.

Третий - это для реализации интерфейса a FormAction, который позволит вам проверить входящую форму на стороне сервера:

Основной интерфейс, который вы должны реализовать, - это интерфейс FormAction. FormAction отвечает за рендеринг и обработку части страницы. Рендеринг выполняется в методе buildPage (), проверка выполняется в методе validate (), операции пост-проверки выполняются успешно ().

@Override
public void validate(ValidationContext context) {
    MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
    UserModel user = context.getUser();
    KeycloakSession session = context.getSession();
    RealmModel realm = context.getRealm();

    String newYourCustomAttribute1 = formData.getFirst("yourCustomAttribute1");
    String oldYourCustomAttribute1 = user.getFirstAttribute("yourCustomAttribute1") 

    if (!newYourCustomAttribute1.equals(oldYourCustomAttribute1)) {
        Response challenge = context.form()
                .setError("User cannot change the attribute")
                .setFormData(formData)
                .createResponse(UserModel.RequiredAction.UPDATE_PROFILE);
        context.challenge(challenge);
        return;
    }
    context.success();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...