How to impose authentication to access Forge Web Trigger?

Hi,

Currently, when I built Forge Web Trigger, it allows everyone to access the web trigger URL.
Please help if we can impose authentication to access the web trigger URL?

Thank you,
Bharadwaj Jannu

Unfortunately, you’ll need to implement your own authentication system in order to do this.

Wow, this fact and limitation should be mentioned in the documentation.

@danielwester did you actually implement something around this? We want to make a generated file available to logged-in users.

Forge looked secured to me so far, but with this, you can make some asApp() calls in the trigger function and then expose publicly all the product information

Are there any tips you could share on implementing an authentication system? I had a look at this, but it’s not quite the same problem.

Hi everyone. I’ve found a workable solution to require basic authentication, if you are happy to allow anyone in your organization to gain access (or anyone allowed by your tenant).

Inside your function, get the Authorization header off the request and reuse that in a requestJira or requestConfluence call, without asUser(). For example (with Jira):

const responseStructure = {
    body: 'string',
    headers: {
        'Content-Type': ['application/json'],
        'X-Request-Id': ['example'],
    },
    statusCode: 200,
    statusText: 'OK',
}

const error = (code, message) => {
    console.log(`Error: ${code} ${message}`);
    return {...responseStructure, statusCode: code, statusText: `${code} ${message}`, body: message};
};

const success = body => {
    return {...responseStructure, body: body};
};

const authenticate = () => {
    const code = 401;
    const text = 'Unauthorized';
    return {...responseStructure, body: `${code} ${text}: Bad username/password combination`, statusCode: code,
        statusText: text, headers: {
            'WWW-Authenticate': ['Basic']
        }};
}

export const myFunc = async (req) => {
    let jsonString = '';
    const {authorization} = req.headers;
    const auth = authorization && authorization.length ? authorization[0] : authorization;

    if (!auth)
        return authenticate();

    try {
        const {ok, status, statusText} = await requestJira(route`/rest/api/3/myself`, {
            headers: {
                "Authorization": auth
            }
        });
        if (!ok)
            return status === 401 ? authenticate() : error(status, `${status} ${statusText}`);
    } catch (e) {
        return error(400, e.message);
    }


    // do your thing with asApp() and set jsonString
    try {
        data = doSomethingWithAsApp();  // whatever that is
        jsonString = JSON.stringify(data, null, 2);
    } catch (e) {
        return error(400, e.message);
    }

    return success(jsonString);
};

Basic auth is not the greatest, but with https it’s at least workable. I hope this helps. I’ll keep investigating other techniques.

1 Like

@MattFlaherty Thanks for sharing this. Is it possible to access the IP of the requestor and only allow requests from a hardcoded set of IPs (on top of basic auth) ? Thanks

Look to see what fields come through on the req parameter. I have a feeling IP address is in there somewhere.

1 Like

ok thanks