Script based testing in browser based auth scenario - authentication

We have a web api where auth token is generated after invoking a browser based authentication. How can this be automated via script in a CI/CD pipeline where there wouldn't be a user action

The details depend on your concrete technology stack, but you will have to use a headless browser, as pointed out in the comments. This is a software that behaves like a browser but doesn't have a UI and is controlled through scripts. Have a look at cypress.io as they have a really good tool for what you need.
You can have a look at this example we've created at Curity: https://github.com/curityio/redirect-action-example/blob/master/tests/cypress/e2e/authenticationAction.cy.js This shows a Cypress test that performs user authentication through a headless browser and gets an ID token from the response.
In this repo you will also find a definition of GitHub Actions workflow, so you can check how we put all these together and test via GitHub Actions.
If your authentication flow is a simple one, you can actually script it using curl commands. Curl is able to send and receive cookies, so it can mimic browser requests. With curl you will have to hardcode what requests are being sent and their model, so it might be a bit more tricky with some complicated flows. Here's another example we've created at Curity, where curl is used to perform the login flow: https://github.com/curityio/oauth-agent-kotlin-spring-fapi/blob/master/test/login.sh

Have you considered unit-testing API (resource-server) access control with mocked identities instead of writing end-to-end tests involving at least three OAuth2 actors (resource-server, authorization-server and client)?
This would be much simpler, faster and stable.
If you are using Spring framework for your API, visit this repo. I have quite a few samples and tutorials covering most OAuth2 possible configuration options with Unit and integration tests focused on access-control.

Related

Imitate Keycloak user creation/login/deletion via API, for acceptance testing purposes

I have a microservices-based application secured by Keycloak. To carry out API-level acceptance and platform testing. I would like to emulate as closely as possible the creation/login/deletion of a user account from the point-of-view of the user - without creating/controling a browser, headless or otherwise.
I realise I can directly carry out these operations by creating a realm client with client credentials but I would like to avoid this since:
it does not closely emulate the interactions I'm seeking to test
it presents a potential security risk in giving an outside entity rights to edit and delete accounts which it doesn't own.
When running against production it potentially allows the tests to accidentally edit/delete real accounts.
As far as I understand, the closest way to emulate these actions would be to imitate the http requests carried out by the Keycloak user web interface. I imagine I could reverse-engineer these via browser development tools but but was wondering if there was a less time-consuming and brittle alternative
Are these http requests documented anywhere?
Is there an alternative API which directly models thse interactions?

How to skip MFA in e2e tests?

I have some difficulties with automating log in process in the web application. It's an angular app, I'm writing tests in protractor. The app uses Azure AD, so I need to pass e-mail, password and the verification code from mobile app. I know there're some very useful libraries to generate the code. The problem is I don't have the access to Azure admin panel so I'm not able to get the secret key that is necessary to use those libraries. Is it possible to somehow skip or mock the MFA? I'd be grateful for any advices how to solve this.
Assuming you want to run these tests on the CI, you could hard code a test user credential in your web application that returns true when used in a specific environment. Lets say you want user xyz#abc.com to login and then perform other tasks, add code in your web application so that when xyz#abc.com sends a request with dummy secret key, log the user in. Then you'd have to mock all the rest of the APIs that your application uses.
You can also remove the auth when you are testing it in a test CI environment. This would be a good solution but tricky. You would have to remove auth entirely for all APIs and that would require design pattern change etc.
But get the access and do it the right way.
I would actually recommend NOT skipping MFA on E2E tests in your CI.
By setting up a bypass in your code related to your environments you are taking the risk of having this "test account" in the production environment and being it found by someone. And believe me, it will happen sooner or later ;).
Today multiple third-party tools exist allowing you to parse SMS-based MFA or TOTP codes (like the Azure app). For example, the GetMyMFA platform provides you with an API allowing you to receive and inject in your CI your MFA codes.
If you have the time and resources, I would recommend looking for a tool that allows you to get MFA codes from an API and have your automated E2E tests inject that code in your CI.
Cheers

Jenkins + Crowd2 plugin: execute API from 3rd party application

Goal:
I want do write an application that can trigger Jenkins jobs and itself also authenticates users against the Crowd server. The users must be in a separate crowd group to be authorized to act on Jenkins.
Setup:
I am using the Crowd2 plugin to authenticate Jenkins users against an Atlassian Crowd 2.1 server.
My thoughts:
Now, Jenkins has two types of remote execution:
Jenkins REST API (uses a per-user Token for authentication)
A build can be triggered through this call using a "TOKEN" in a way like this:
JENKINS_URL/job/JOBNAME/build?token=TOKEN
Jenkins CLI (uses an SSH key for authentication)
A build can be triggered through an command line tool using the SSH private key to authenticate the user.
The token-approach (REST API)...
... requires my application to know the API token.
How could I bypass the API token limitation?
Storing the API token within Crowd?
The Crowd2 Jenkins plugin could store the Jenkins API token as an crowd attribute (user-defined properties which can be stored within the crowd user directory), is one way. Even though I think this could be a security flaw, as the attribute might be retrieved from all other applications registered at Crowd (which would enable them to execute Jenkins jobs on the users behalf).
Q: Good approach and secure enough? In my opinion, this is not secure enough.
Authenticating with my applications crowd token against Jenkins?
I've also tried generating a crowd-token through Crowd's API and then requesting the Jenkins REST API with that token as Cookie in the hope that the Jenkins crowd2 plugin validates the passed Crowd token against Crowd. But it does not work (when using the crowd token from my browser, by examining the page information in Firefox, it works, of course).
I am not sure if this approach (if the crowd2 plugin would check the passed token) has security flaws in it and if the crowd-token mechanism is designed to work in that way. I am sure though, that it might negatively affect Jenkins' performance as every API request has to check if the token is valid.
Q: Good approach and possible?
The CLI-approach...
...requires my application to know a SSH private key registered at Jenkins.
It would be good approach, if Jenkins would support adding SSH Keys. My application could generate a SSH key pair (with random) password and automatically store the public key on the users behalf within Jenkins.
I think this is the right way, even though it requires to extend Jenkins and maybe the authentication plugins.
Q: Is this approach possible and secure enough?
Q: Are there other approaches?
I think Jenkins should implement an OAuth endpoint for authorization (in case of the crowd plugin, it then has to delegate the authorization to Crowd) or completely detach user management from its core. Am I wrong?
Please help me improving this question, if neccessary. I can imagine that I've mixed two problems and didn't described by goal clear enough.
Note: Edited this question ~1 hr after creation (see my 1st comment).

Selenium and SSO

I need to run my Selenium Webdriver JUnit tests separately, but also all at once. I've been looking for a solution for something that basically cuts down to one single issue: I'm testing an application which uses SSO.
That means, I have to manually sign in when I run a test. This is on the other hand even desired, because you don't want to store critical passwords in any files. This is not even harmfull when you run a single test. But when you're in need to run them all, and you have about 100 tests, you would have to sign in 100 times. No way Jose!
I have found out that one possible solution could be Java proxy server. I find codes that show how to create and handle one, but not the SSO part in it. Can anyone help me? Or will the password be stored somewhere either ways?
You need to find out more about your SSO implementation. I suggest using your browser's developer tools our a debugging proxy such as Fiddler or Charles to capture the HTTP traffic between your browser and the servers during SSO authentication, then implementing these requests in a Java web client. SSO authentication often results in setting a cookie. If you capture this cookie after the authentication phase, then you can reuse this cookie in every Selenium test.
The authentication will require credentials, which you could put into a properties file. You could exclude this properties file from source control, and ask all developers to use their own credentials when running tests.

Use everyauth package for authorizing users to access data via REST api calls

I am developing a google chrome extension that needs to communicate with a nodejs server. I was wondering if its possible to use everyauth package to simplify authentication. For starters, I just wanted to use simple password based authentication. But from the examples and the documentation ,as well according to my trial, it seems to me that everyauth is designed to be used for a webapp and gives me errors if i don't set the getLoginPath. Also i am not sure how to configure everyauth to send the user details or errors after user authenticate in a json payroll rather than redirecting user to a particular page. This is my first project with node.js and I am looking for some advice on how to go forward with this. I am open to using some other package/library that provides such authentication,
Since you are open to using other modules, as the developer of Passport, I'd suggest you look at it: https://github.com/jaredhanson/passport
Passport is designed to be a simple and unobtrusive authentication library, which makes it easy to get up and running quickly. It's also modular and extensible, which allows it to adapt to your applications needs over time.
The examples provided, along with the local strategy ( https://github.com/jaredhanson/passport-local ) are enough to get you started with username/password authentication. Let me know if you have any feedback or questions.
I was able to accomplish a REST-only interface to everyauth by overriding its handler methods: https://gist.github.com/2938492