Quantcast
Channel: RequestFactory is null inside Confluence Custom Seraph Authenticator - Stack Overflow
Viewing all articles
Browse latest Browse all 2

RequestFactory is null inside Confluence Custom Seraph Authenticator

$
0
0

This is a copy of a question I asked on the Atlassian forums

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
  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("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 approach is simply

ComponentLocator.getComponent(RequestFactory.class);

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


EDIT

Re-reading the Seraph article, 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 found here, works fine

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

Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596344.js" async> </script>