Seraph-Can't get SAL for remote Service Call
Asked by Miguel Mendez:

I've been trying to make my own custom authentication plugin for SSO with my company using Seraph in Confluence (And will late do so in Jira) but I can't seem to make remote Service calls because I can't find the *RequestFactory* SAL.

Here are the rough steps I've taken so far

1. Download/Setup SDK
2. Create Confluence Plugin
3. Extended the *ConfluenceAuthenticator* class and implemented my own logic

Now I'm trying to get a reference to the RequestFactory SAL and have tried,

1. Dependency injection with annotations
2. [Dependency injection with contructor](https://developer.atlassian.com/plugins/scroll-viewport/draft/7F000101014A533132D9CDB212BD5E1B/atlassian-platform-common-components/shared-access-layer/sal-services)
3. ComponentLocator
4. *component-import* xml tag (docs are out of date and doesn't work)

So, my question is, how would I get access to the RequestFactory for making remote calls in Seraph?

When using the below code, if using ComponentLocator approach it returns *null*, and when using Dependency Injection it tells me the class couldn't be instantiated

```
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 more
```

===

Here's the code so far

Targeting *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("MyCustomAuthenticator::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 SSO");
??????????? 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")
??????????????????? .execute();
??????????? log.info("results: " + s);
??????? } catch (ResponseException e) {
??????????? e.printStackTrace();
??????? }

??????? return (Principal)user;
??? }
}
```

*ComponentLocator* approach is simply

```
ComponentLocator.getComponent(RequestFactory.class);
```

but like, i said, always returns null ? also tried `PluginSettingsFactory.class` and it also returns null


Answers:
author: Jakob Englisch
body: I'm also unable to use RequestFactory with Atlassian Spring Scanner 2.x using multiple approaches. Injecting TrustedRequestFactory works just fine. It seems this is currently broken, which is a pitty.


author: Miguel Mendez
body: Re-reading the [Seraph article](https://confluence.atlassian.com/kb/single-sign-on-integration-with-the-atlassian-stack-794495126.html), I realized that dependency injection is not available to Seraph and there are a few caveats when looking for other Components (like RequestFactory).

Which leads to

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

However, now the error has changed to

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

Also tried

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

with no luck either, says it can't be found

I CAN get other components though, for example using the [example](https://developer.atlassian.com/confdev/development-resources/confluence-developer-faq/how-do-i-get-a-reference-to-a-component) found here, works fine

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


author: Miguel Mendez
body: I managed to find an alternate solution to communicating with an external service

---

So, a few things for those looking at this:

1. Seraph requires any java jar, not specifically a atlassian-plugin
2. You can use any method you wish to communicate with the outside world

I managed to communicate using the built in Java HttpUrlConnection. Its super gross to use but works perfectly. I'd abandon the idea of using SAL inside of seraph if someone finds this thread

Here's an example to get started:

```
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;    }
```

Copy/pasta from

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

But you can find many examples online on how to use this

Posted as well to Stackoverflow so more can see this

[https://stackoverflow.com/questions/47846217/requestfactory-is-null-inside-confluence-custom-seraph-authenticator/48302933#48302933](https://stackoverflow.com/q/47846217/1293521)

comments: author: Florian Maupas
body: [@Miguel Mendez](/t5/user/viewprofilepage/user-id/1140473) Thank you so much for your post.

I spent 2 days trying to figure out how to make this RequestFactory working and I had the exact same issue.

I ended up applying the same workaround you provided.

Premium Support should provide an explanation for this issue/bug...


author: Kerkko Pelttari
body: Same problem. Been trying to use RequestFactory with multiple approaches for 3 days now.


Tags: app

authentication

sso