RequestFactory имеет значение null внутри Confluence Custom Seraph Authenticator

Это копия вопроса, который я задал на форумы Atlassian

Я пытался создать свой собственный подключаемый модуль аутентификации для SSO с моей компанией, используя Seraph в Confluence (и позже сделаю это в Jira), но я не могу совершать удаленные вызовы службы, потому что я не могу найти RequestFactory SAL.

Вот грубые шаги, которые я предпринял до сих пор:

  1. Скачать/установить SDK
  2. Создать плагин слияния
  3. Расширен класс ConfluenceAuthenticator и реализована моя собственная логика

Теперь я пытаюсь получить ссылку на RequestFactory SAL и пробовал,

  1. Внедрение зависимостей с аннотациями
  2. Внедрение зависимостей с помощью конструктора
  3. ComponentLocator
  4. Тег component-import xml (документы устарели и не работают)

Итак, мой вопрос: как мне получить доступ к RequestFactory для совершения удаленных вызовов в Seraph?

При использовании приведенного ниже кода, если используется подход ComponentLocator, он возвращает значение null, а при использовании внедрения зависимостей он сообщает мне, что класс не может быть создан.

Caused by: com.atlassian.seraph.config.ConfigurationException: Unable to instantiate class 'com.example.confluence.GluuAuthenticator' : java.lang.InstantiationException: com.example.confluence.MyCustomAuthenticator
        at com.atlassian.seraph.config.SecurityConfigImpl.configureClass(SecurityConfigImpl.java:325)
        at com.atlassian.seraph.config.SecurityConfigImpl.configureAuthenticator(SecurityConfigImpl.java:258)
        at com.atlassian.seraph.config.SecurityConfigImpl.<init>(SecurityConfigImpl.java:194)
        at com.atlassian.seraph.config.SecurityConfigFactory.loadInstance(SecurityConfigFactory.java:56)
        ... 131 more
Caused by: java.lang.InstantiationException: com.example.confluence.MyCustomAuthenticator
        at java.lang.Class.newInstance(Class.java:427)
        at com.atlassian.seraph.config.SecurityConfigImpl.configureClass(SecurityConfigImpl.java:320)
        ... 134 more
Caused by: java.lang.NoSuchMethodException: com.example.confluence.MyCustomAuthenticator.<init>()
        at java.lang.Class.getConstructor0(Class.java:3082)
        at java.lang.Class.newInstance(Class.java:412)

... еще 135

Вот код на данный момент

Таргетинг Confluence 6.4

import com.atlassian.confluence.user.ConfluenceAuthenticator;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.sal.api.net.Request;
import com.atlassian.sal.api.net.RequestFactory;
import com.atlassian.sal.api.net.ResponseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Principal;

public class MyCustomAuthenticator extends ConfluenceAuthenticator {
    private static final Logger log = LoggerFactory.getLogger(ConfluenceAuthenticator.class);
    private static final String CODE_PARAM_NAME = "code";

    @ComponentImport
    private final RequestFactory<?> requestFactory;

    @Inject
    public MyCustomAuthenticator(@ComponentImport RequestFactory<?> requestFactory) {
        this.requestFactory = requestFactory;
    }

    public Principal getUser(HttpServletRequest request, HttpServletResponse response) {
        log.debug("SMAuthenticator::getUser(HttpServletRequest request, HttpServletResponse response)");
        Principal user = super.getUser(request, response);
        String code = request.getParameter(CODE_PARAM_NAME);

        if (user != null) {
            log.debug("User is already logged in: " +
                    ((user.getName() != null) ? user.getName() : "<None>") );
            return (Principal) user;
        }

        if (code == null) {
            log.debug("User is not logged in, and there is no code found in query params, will redirect to gluu");
            return (Principal) user;
        }


        log.info("User is not logged in, but code is found in the query params. Will start the flow to create the user, " +
                "starting with verifying the code: " + code);

        try {
            String s = requestFactory
                    .createRequest(Request.MethodType.GET, "http://scooterlabs.com/echo")
                    .addBasicAuthentication(CLIENT_ID, CLIENT_SECRET, "fooooo")
                    .execute();
            log.info("results: " + s);
        } catch (ResponseException e) {
            e.printStackTrace();
        }

        return (Principal)user;
    }
}

ComponentLocator подход прост

ComponentLocator.getComponent(RequestFactory.class);

но, как я уже сказал, всегда возвращает null ???? также пробовал PluginSettingsFactory.class, и он также возвращает null


ИЗМЕНИТЬ

Перечитывая статью Seraph я понял, что внедрение зависимостей недоступно для Seraph, и есть несколько предостережений при поиске других компонентов (например, RequestFactory).

Что приводит к

RequestFactory requestFactory = (RequestFactory)ContainerManager
        .getComponent("requestFactory");

Однако теперь ошибка изменилась на

com.atlassian.spring.container.ComponentNotFoundException: Failed to find component: No bean named 'requestFactory' is defined

Также пробовал

RequestFactory requestFactory = (RequestFactory)ContainerManager
        .getInstance()
        .getContainerContext()
        .getComponent(RequestFactory.class);

тоже не повезло, говорит, что не может быть найдено

Я МОГУ получить другие компоненты, например, используя пример, найденный здесь, отлично работает

SpaceManager spaceManager = (SpaceManager) ContainerManager.getComponent("spaceManager")

person ObjectiveTruth    schedule 16.12.2017    source источник


Ответы (1)


Мне удалось найти альтернативное решение для связи с внешней службой


Итак, несколько вещей для тех, кто смотрит на это:

  1. Для Seraph требуется любой java jar, а не плагин atlassian.
  2. Вы можете использовать любой способ связи с внешним миром.

Сказав это, вы можете использовать сборку в HttpUrlConnection в Java. Его супер грубый в использовании, но работает отлично. Я бы отказался от идеи использовать SAL внутри seraph, если кто-то найдет эту тему

Вот пример для начала:

try
    {
      // create the HttpURLConnection
      url = new URL(desiredUrl);
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
      
      // just want to do an HTTP GET here
      connection.setRequestMethod("GET");
      
      // uncomment this if you want to write output to this url
      //connection.setDoOutput(true);
      
      // give it 15 seconds to respond
      connection.setReadTimeout(15*1000);
      connection.connect();

      // read the output from the server
      reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
      stringBuilder = new StringBuilder();

      String line = null;
      while ((line = reader.readLine()) != null)
      {
        stringBuilder.append(line + "\n");
      }
      return stringBuilder.toString();
    }
    catch (Exception e)
    {
      e.printStackTrace();
      throw e;
    }

Копировать/вставить из

https://alvinalexander.com/blog/post/java/how-open-url-read-contents-httpurl-connection-java

Но вы можете найти много примеров в Интернете о том, как использовать это

person ObjectiveTruth    schedule 17.01.2018