Authorization in Sonar REST/Web API - sonarqube

I have migrated my Sonar version from 5.4 to 6.3.1.
In 5.4 version, there was no login API provided by Sonar.
Hence we were adding an Authorization header in every call with value as Base64 encoded "username":"password".
But post migration to 6.3.1, the authorization fails with current implementation.
We tried passing token (generated from UI) as value of Authorization header but in vain.
We also tried calling Sonar login API (api/authentication/login) but it is not giving back any response.
Kindly help us resolve this issue.
Thanks.
Edit
Following is the code for calling REST Webservice:
byte[] encodedUsernamePassword = Base64.getEncoder().encode("adminUserName:adminPassword".getBytes());
ResteasyClient client = new ResteasyClientBuilder().build();
String target = "http://IP:Port/api/issues/search/?statuses=" + "CLOSED" + "&assignees=" + username + "&resolutions=" + "FIXED" + "&createdBefore=" + end_date + "&createdAfter=" + start_date + "&facetMode=debt";
javax.ws.rs.core.Response response = client.target(target).request(MediaType.APPLICATION_JSON).header("Authorization", new String(encodedUsernamePassword)).get();
String strResponse = response.readEntity(String.class);

First thing: api/authentication/login is of no help here. Per Web API documentation , Web API authentication is made through HTTP basic authentication.
So just pass the username/password in the header of each Web API request. And if you use User Tokens, as per same documentation:
This is the recommended way. Benefits are described in the page User Token. Token is sent via the login field of HTTP basic authentication, without any password.

Two changes were made in above code:
Added 'Basic' prefix to the value of Authorization header as follows:
header("Authorization", new String("Basic YWRtaW46YWRtaW4zMjW="))
Removed extra '/' before '?'from below URL as shown below:
http://IP:Port/api/issues/search/?statuses

Related

Google Identity for server-side web app - redirect URI mismatch

I'm attempting to set up the Code Model for Google authentication, so that my user can oauth with Google and my app can retrieve their Calendar data. I'm stuck on step 5 here, where I'm supposed to exchange the authorization code for refresh and access tokens. I'm using nestjs in the backend and React in the frontend.
What I've done already that's working:
User clicks a button on my web app's page
Client sets up google.accounts.oauth2.initCodeClient with the /calendar scope, in ux_mode: popup
User is shown the Google popup and can auth thru that
Client receives a response from Google containing the authorization code
Client makes a POST call to my backend to send it just that authorization code
In step 5, the client makes the POST call to localhost:4000/auth/google-test. In the backend, I'm using the googleapis package and have:
export const oauth2Client = new google.auth.OAuth2(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
'http://localhost:4000/' // <- note, I'm not sure if this is corect
);
And in the relevant controller route, I'm doing:
#Post('google-test')
public async googleTest(#Body() bodyReceived: any): Promise<any> {
let { code } = bodyReceived
let { tokens } = await oauth2Client.getToken(code)
oauth2Client.setCredentials(tokens);
console.log('Tokens: ' + tokens);
return
The error I'm getting is related to oauth2Client.getToken(code), and the error is a redirect_uri_mismatch. In GCP for the credentials for this app, I've added all of these as "Authorized redirect URIs":
http://localhost:3000/home
http://localhost:4000/auth/google-test
http://localhost:4000
What am I doing wrong?
It took a bit more Googling, but turns out that the right answer is to have my server make the token call with the redirect uri as "postmessage".
This SO question gives a bit more context. A somewhat unbelievable message, but it seems to work for my app.
It is evidently that what is happening is that the redirect URI does not match with the one in the GCP. This usually happens because backend tools such as Nestjs may be appending a trailing '/' to the URL and it may be interpreted as being part of the redirect_uri value.
You can try by temoving any trailing '/' via this following method oauthurl.replace(/\/$/, '')
Moreover, you can pass the generated auth URL to a meta tag. And check the html header to confirm what is the URL value.

dotnetopenauth with AzureAD b2c

I am using dotnetopenauth (version 4) to obtain an accesstoken for my Api. This works perfectly fine but i cannot figure out how i can read the profile information for the user (which is send back by Azure AD b2c).
The first leg of the flow is a request to the authorization endpoint. (basically a get request)
After the authorization the callback url is called. In my case this is callback.aspx.
On this callback page i'm running the following dotnetopenauth code:
var authorization = Client.ProcessUserAuthorization();
This will do another post again to the token endpoint. The response looks like this:
{"access_token":"xxxx","token_type":"Bearer","not_before":1519920056,"expires_in":3600,"expires_on":1519923656,"resource":"6ee73e1a-6e96-4ed6-b7f8-a52c1379317a","id_token_expires_in":3600,"profile_info":"eyJ2ZXIiOiIxLjAiLCJ0aWQiOiIyYjIzMTFmMy04ZWNlLTQ3MzMtOWVlNS04ZWMxNzJiOTRjMDMiLCJzdWIiOm51bGwsIm5hbWUiOiJBbGZyZWQgQnJvY2tvdHRlciIsInByZWZlcnJlZF91c2VybmFtZSI6bnVsbCwiaWRwIjpudWxsfQ","refresh_token":"eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMCIsInppcCI6IkRlZmxhdGUiLCJzZXIiOiIxLjAifQ","refresh_token_expires_in":1209600}
As you can see the profile_info is included (as a base64 string). But the IAuthenticationState has no property or function to get this information:
Is there a way to get this extra response data with dotnetopenauth?

OAuth token parameter missing when using request_youtube API

I try to using youtube API in code ingniter and using librari from https://github.com/jimdoescode/CodeIgniter-YouTube-API-Library when i call request_youtube()from direct link the https://accounts.google.com/o/oauth1/auth sent massage like this :
400. That’s an error.
OAuth token parameter missing.
That’s all we know.
This the code of request_youtube() :
public function request_youtube()
{
$params['key'] = xxxxxxxxxxxx.apps.googleusercontent.com';
$params['secret'] = 'xxxxxxxxxxxx';
$params['algorithm'] = 'HMAC-SHA1';
$this->load->library('google_oauth', $params);
$data = $this->google_oauth->get_request_token(base_url().'index.php/example/access_youtube');
$this->session->set_userdata('token_secret', $data['token_secret']);
redirect($data['redirect']);
}
what wrong with my code...or any step i miss???
The library that you are using is deprecated probably because of which it is unable to make calls to the Google Servers and is returning 404 errors. You can still follow the original way of authentication using OAuth where you validate your app with the client id client secret and get the Auth code. With the Auth code making a POST request and getting a access token and a refresh token in exchange. For details please refer to this official Google Youtube Documentation on OAuth.

What was I wrong when using Jersey Client to authenticate an Spring Security web application?

I have a web application which is protected by Spring Security Login Form authentication. Now I want to use Jersey Client to authenticate to my web pages and I think I should pass through login form as I do on a normal browser.
My client authentication code is as below
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/authentication-inmem/j_spring_security_check");
Form form = new Form();
form.param("j_username", "car");
form.param("j_password", "scarvarez");
Response response = target.request()
.post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
System.out.println(response.getStatus());
This code always produces 404 status code.
When I type the link http://localhost:8080/authentication-inmem/j_spring_security_check to my browser or just modify above code to an GET request. I could normally receive HTML code for authentication login form. Hence, I really don't know why this url is not found with an POST?
Hope you could show me what I am wrong here, and moreover, what I am doing is a proper way to authenticate to my server without using a browser?
I have found the answer, by default Jersey client will automatically redirect as soon as it receives a response with status is 3xx. (in this case it is 302).
Now, just turn off the feature by a bit configuration ahead, and I could get the status 302 display on my console.
ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ClientProperties.FOLLOW_REDIRECTS, false);
Client client = ClientBuilder.newClient(clientConfig);

LinkedIn JS API token exchange to REST token using Spring Social for Linkedin

I'm trying to do the following:
Let the user authenticate and authorize through Linkedin using Linkedin JSAPI, then take the authentication details and send them to my server to get the user profile via server side communication.
I got the Linkedin button setup, got the authorization cookie all the way to my server (as described here), and was able to verify that the token is indeed signed correctly with my secret key.
Now I'm stuck at the point where I am supposed to take the token I got from JSAPI and exchange it for an access token.
This is the code I'm using, as mentioned it uses Spring Social for Linkedin, and it doesn't work as it throws a 401 Unauthorized response:
LinkedInConnectionFactory connectionFactory =
new LinkedInConnectionFactory(myLinkedinId, myLinkedinSecret);
OAuth1Operations oauthOperations = connectionFactory.getOAuthOperations();
AuthorizedRequestToken art = new AuthorizedRequestToken(new OAuthToken(codeIGotFromJSAPI, aSecretKey), whereDoIGetThisSignature);
OAuthToken accessGrant = oauthOperations.exchangeForAccessToken(art, null);
if (accessGrant == null) return null;
Connection<LinkedIn> connection = connectionFactory.createConnection(accessGrant);
if (connection != null) {
LinkedIn linkedin = connection.getApi();
return linkedin.profileOperations().getUserProfile();
}
What I'm actually confused about is the AuthorizedRequestToken object. The codeIGotFromJSAPI part is simple enough I think, it's just access_token, but what about aSecretKey, is it just my linkedin secret key? what about whereDoIGetThisSignature, how do I create that one? Do I use the same hash method as I used to validate the linkedin response and hash the access_token with my secret linkedin key? In the linkedin page, it says:
You need to pass four values as query parameters:
oauth_consumer_key, to identify yourself
xoauth_oauth2_access_token parameter, set to the value of the access_token field in the cookie.
signature_method set to HMAC-SHA1
signature, calculated as described in the OAuth 1.0a spec
So (1) is automatically done by the connection I suppose, (2) is the access token I provided, but how do I do (3) and (4)?
Lets suppose I get the following data in the JSAPI cookie set by Linkedin:
{
"signature_method":"HMAC-SHA1",
"signature_order": ["access_token", "member_id"],
"access_token":"AD2dpVe1tOclAsNYsCri4nOatfstw7ZnMzWP",
"signature":"73f948524c6d1c07b5c554f6fc62d824eac68fee",
"member_id":"vvUNSej47H"
"signature_version": 1
}
What do I need to do with it to go through the next step?
Use the following process:
Read the cookie
Transform "signature":"..." to &signature=...
Transform "signature_method":"HMAC-SHA1" to &signature_method=HMAC-SHA1
Transform "member_id":"..." to &oauth_customer_key=...
Transform "access_token":"..." to &xoauth_oauth2_access_token=...
Append all to the LinkedIn url plus ?
The LinkedIn JSAPI Token Exchange as described in Exchange JSAPI Tokens for REST API OAuth Tokens is currently not supported by Spring Social, according to a Spring forum discussion on this topic.
But there are implementation available to solve this task without Spring Social by using standard OAuth libraries available for Java. The LinkedIn user's access token, that you get from the exchange, can be put into a new AccessGrant object which can be used to create a Spring Social Connection<?> in the user's ConnectionRepository.
The code published in the LinkedIn developer forum discussion shows how to use Scribe to perform the exchange. The request that has to be sent to LinkedIn is a standard OAuth request but must ship the access_token field from the JSAPI token object as a HTTP query parameter xoauth_oauth2_access_token. The member_id that is also available to you is just for your information, and the signature allows you to verify both access_token and member_id without querying LinkedIn.

Resources