Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot set Authorization via extraHeaders #1700

Closed
4imble opened this issue Oct 16, 2024 · 9 comments · Fixed by #1702
Closed

Cannot set Authorization via extraHeaders #1700

4imble opened this issue Oct 16, 2024 · 9 comments · Fixed by #1702

Comments

@4imble
Copy link

4imble commented Oct 16, 2024

I am trying to authenticate against a 3rd party system and that requires setting a bearer token on the /token endpoint. (seems odd to me, but I cant change it)
I tried setting this via extraHeaders unfortunately this is not working.
I have checked the code and it seems this has explicitly been blocked.
I don't suppose this can be allowed?

private appendExtraHeaders(
        headers: Record<string, string>,
    ): void {
        const logger = this._logger.create("appendExtraHeaders");
        const customKeys = Object.keys(this._extraHeaders);
        const protectedHeaders = [
            "authorization", // <==================================== BLOCKED!
            "accept",
            "content-type",
        ];
        if (customKeys.length === 0) {
            return;
        }
        customKeys.forEach((headerName) => {
            if (protectedHeaders.includes(headerName.toLocaleLowerCase())) {
                logger.warn("Protected header could not be overridden", headerName, protectedHeaders);
                return;
            }
            const content = (typeof this._extraHeaders[headerName] === "function") ?
                (this._extraHeaders[headerName] as ()=>string)() :
                this._extraHeaders[headerName];
            if (content && content !== "") {
                headers[headerName] = content as string;
            }
        });
    }
@pamapa
Copy link
Member

pamapa commented Oct 16, 2024

I guess the protection is because of this code before:

if (basicAuth !== undefined) {
  headers["Authorization"] = "Basic " + basicAuth;
}

or

if (token) {
  logger.debug("token passed, setting Authorization header");
  headers["Authorization"] = "Bearer " + token;
}

I think we can allow "Authorization" unless its already part of the headers...

@4imble
Copy link
Author

4imble commented Oct 16, 2024

Allowing token in this situation would work for me too. but it's not checking for that parameter (only basicAuth) in this situation so I am unable to set it.

@pamapa
Copy link
Member

pamapa commented Oct 16, 2024

Does this work for you? #1702

@pamapa
Copy link
Member

pamapa commented Oct 16, 2024

Allowing token in this situation would work for me too. but it's not checking for that parameter (only basicAuth) in this situation so I am unable to set it.

What is your call stack? Are you using this library as an SDK? If so, we can simply add an addiotional parameter to set the token directly...

@4imble
Copy link
Author

4imble commented Oct 16, 2024

I am using it via the react-oidc-context.
My config essentially looks something like this... (I have appended the token parameter which which I would like it to set)

const oidcConfig = {
  authority: 'https://wd.api.com', // This can be a dummy value if metadata is provided
  client_id: 'fisuhfsdiuhdsfiuhdsiuh',
  redirect_uri: 'https://localhost:5001',
  response_type: 'code',
  scope: 'OpenId',
  extraQueryParams: { tenantAlias: 'my_tenant' },
  token: 'ID saiuhsaiuhdsaiuhasduihda', //<============= NOT CURRENTLY IMPLEMENTED
  onSigninCallback: onSigninCallback,
  metadata: {
    issuer: 'https://wd.api.com/auth/v1',
    authorization_endpoint: 'https://wd.api.com/auth/v1/authorize',
    token_endpoint: 'https://wd.api.com/auth/v1/token',
    userinfo_endpoint: 'https://wd.api.com/auth/v1/userinfo',
    jwks_uri: 'https://wd.api.com/auth/v1/jwks',
    end_session_endpoint: 'https://wd.api.com/auth/v1/logout',
  },
};

I am currently able to get the code from /authorize however /token requires a bearer token in the in the headers that looks like this Authorize: 'Bearer ID saiuhsaiuhdsaiuhasduihda'

I should note that I have confirmed that calling my /token endpoint with the token above is allowing me to get the real bearer token back correctly instead of getting 401 Unauthorized

@pamapa
Copy link
Member

pamapa commented Oct 17, 2024

Can you provide the call stack you are using? As you said "only basicAuth" i guess the last call is postForm? I thinking about adding an additional token parameter, but the question is where else would i need to add it too...

@4imble
Copy link
Author

4imble commented Oct 17, 2024

Apologies, you meant the literal call stack - my mistake.
Is this adequate?

image

@pamapa
Copy link
Member

pamapa commented Oct 17, 2024

Ok, as you said in the beginning this is a very strange IdP behavior.
How can this even work in the first place, where you do not yet have a token anyway?

I do not think we should all the way down here a token parameter. The extra header trick must be good enough. Can you try my prepared MR if that works for you?

@4imble
Copy link
Author

4imble commented Oct 17, 2024

I have grabbed the code 75cd882 and given it a try, it does seem to indeed work. I am now able to get back the bearer token from the API.
The API '/token' endpoint uses a Base64 representation on the ClientId as the auth token which to me seems redundant as that is not secret information and will add no extra layer of security... but as I said, it's 3rd party and I cant change it.
Many thanks for your help, I really appreciate your time in helping getting this resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants