как переопределить весенние рамки бобов? - PullRequest
0 голосов
/ 18 февраля 2020

Я хочу настроить некоторые коды сервера авторизации OAuth, предоставляемые Spring Security. код, ответственный за генерацию / oauth / authorize, является компонентом с именем AuthorizationEndpoint. в классе AuthorizationServerEndpointsConfiguration следующий код создает компонент класса AuthorizationEndpoint:

@Bean
public AuthorizationEndpoint authorizationEndpoint() throws Exception {
    AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint();
    FrameworkEndpointHandlerMapping mapping = getEndpointsConfigurer().getFrameworkEndpointHandlerMapping();
    authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access"));
    authorizationEndpoint.setProviderExceptionHandler(exceptionTranslator());
    authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error"));
    authorizationEndpoint.setTokenGranter(tokenGranter());
    authorizationEndpoint.setClientDetailsService(clientDetailsService);
    authorizationEndpoint.setAuthorizationCodeServices(authorizationCodeServices());
    authorizationEndpoint.setOAuth2RequestFactory(oauth2RequestFactory());
    authorizationEndpoint.setOAuth2RequestValidator(oauth2RequestValidator());
    authorizationEndpoint.setUserApprovalHandler(userApprovalHandler());
    return authorizationEndpoint;
}

Я хочу переопределить его новым пользовательским компонентом. Я создал класс, который расширяет AuthorizationEndpoint. сейчас я вставил тот же код в этот новый класс.

public class AuthorizationEndpointCustom extends AuthorizationEndpoint {

, создавая bean-компонент:

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    AuthorizationServerEndpointsConfiguration asec;


    @Bean
//  @Order(value = Ordered.LOWEST_PRECEDENCE)
    @Primary
    public AuthorizationEndpoint authorizationEndpoint () {

        AuthorizationEndpointCustom authorizationEndpoint = new AuthorizationEndpointCustom();
        FrameworkEndpointHandlerMapping mapping = asec.getEndpointsConfigurer().getFrameworkEndpointHandlerMapping();
        authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access"));
        authorizationEndpoint.setProviderExceptionHandler(asec.getEndpointsConfigurer().getExceptionTranslator());
        authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error"));
        authorizationEndpoint.setTokenGranter(asec.getEndpointsConfigurer().getTokenGranter());
        authorizationEndpoint.setClientDetailsService(clientDetailsService);
        authorizationEndpoint.setAuthorizationCodeServices(asec.getEndpointsConfigurer().getAuthorizationCodeServices());
        authorizationEndpoint.setOAuth2RequestFactory(asec.getEndpointsConfigurer().getOAuth2RequestFactory());
        authorizationEndpoint.setOAuth2RequestValidator(asec.getEndpointsConfigurer().getOAuth2RequestValidator());
        authorizationEndpoint.setUserApprovalHandler(asec.getEndpointsConfigurer().getUserApprovalHandler());

        return authorizationEndpoint;
    }

    private String extractPath(FrameworkEndpointHandlerMapping mapping, String page) {
        String path = mapping.getPath(page);
        if (path.contains(":")) {
            return path;
        }
        return "forward:" + path;
    }

, когда я пытаюсь создать bean-компонент этого нового класса, я сталкиваюсь со следующим ошибка:

Приложение не удалось запустить


Описание:

Компонент authorizationEndpoint, определенный в org.springframework.security.oauth2.config. annotation.web.configuration.AuthorizationServerEndpointsConfiguration, не удалось зарегистрировать. Компонент с таким именем уже определен в ресурсе пути к классу [com / example / demo / AuthorizationServerConfig.class], и переопределение отключено.

Действие:

Рассмотрите возможность переименования одного из компонентов или включив переопределение, установив spring.main.allow-bean-definition-overriding = true

, ошибка исчезнет, ​​добавив предложенный конфиг в application.properties. но новый компонент не заменяет базовый компонент. в другой части моего кода я получил доступ к AuthorizationEndpoint из applicationContext. Я вызвал .getClass () этого объекта, и это тот же бин из фреймворка:

"org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint"

как я могу заставить пружину использовать мой боб?

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

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

@SpringBootApplication(exclude=<AuthorizationServerEndpointsConfiguration>.class)

, но решение переопределения конечных точек каркаса гораздо проще. Все, что нам нужно сделать, - это создать контроллер с отображением для / oauth / authorize

Настройка пользовательского интерфейса Большинство конечных точек сервера авторизации используются в основном на машинах, но есть несколько ресурсов, которым требуется пользовательский интерфейс, и это GET для / oauth / verify_access и ответ HTML из / oauth / error. Они предоставляются с использованием реализаций whitelabel во фреймворке, поэтому большинство реальных экземпляров Сервера авторизации захотят предоставить свои собственные, чтобы они могли контролировать стилизацию и контент. Все, что вам нужно сделать, это предоставить контроллеру Spring MVC @RequestMappings для этих конечных точек, и значения по умолчанию для структуры будут иметь более низкий приоритет в диспетчере. В конечной точке / oauth / verify_access вы можете ожидать, что AuthorizationRequest привязан к сеансу, переносящему все данные, необходимые для получения одобрения пользователя (реализация по умолчанию - WhitelabelApprovalEndpoint, поэтому ищите начальную точку для копирования). Вы можете получить все данные из этого запроса и отобразить их так, как вам нравится, а затем все, что нужно сделать пользователю, это отправить POST обратно в / oauth / authorize с информацией об утверждении или отклонении гранта. Параметры запроса передаются непосредственно UserApprovalHandler в AuthorizationEndpoint, поэтому вы можете интерпретировать данные более или менее по своему усмотрению. UserApprovalHandler по умолчанию зависит от того, предоставили ли вы ApprovalStore в свой AuthorizationServerEndpointsConfigurer (в этом случае это ApprovalStoreUserApprovalHandler) или нет (в этом случае это TokenStoreUserApprovalHandler). Стандартные обработчики утверждения принимают следующее:

читать больше здесь .

есть еще один вопрос, связанный с этим вопросом: читать здесь

0 голосов
/ 18 февраля 2020

Вам нужен Configuration класс

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public AuthorizationEndpoint authorizationEndpoint() {
        if(...) return new AuthorizationEndpoint();
        else return new AuthorizationEndpointCustom();
    }
}
...