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
Related
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.
Consider a developer portal where a developer can create an OAuth2 application Acme Pay. The dev gets a client_id, client_secret, access_token, and a refresh_token, along with a redirect_uri field that can be configured.
The state of the app will be in a test/sandbox environment and the dev can play around within the constraints of the sandbox environment.
As a next step, once the developer has implemented the app locally and wants to push it to prod, I am ideating a flow where the dev would be able to simply toggle the app's environment to a live environment in the developer portal where they get a new token pair for the same app, along with environment-specific access privileges and rate-limits.
I'm a PM trying to understand if such an implementation is possible with OAuth2.
My motivation here is to prevent the developer from creating two OAuth apps for testing and production. I noticed a similar flow in Stripe. Although in my case, the developer will be able to create multiple OAuth apps under one account, hence I feel it is better for each app to have two environments co-existing parallelly at the app level to provide a better developer experience.
The OAuth client configuration is created separately for each stage of your deployment pipeline. Sometimes in portals the wording is Create Application but these are just security related configuration settings.
Separate config per stage of the pipeline enables settings to be versioned reliably over time and tested first. Also the change ownership is often controlled by different people and done at different times. Typically though the deployment is automated in a parameterized and reliable manner.
The actual application code should only ever be built into binaries once though. It is then pushed down a pipeline where binaries are combined with the stage specific configuration.
I have a web application which runs until now with cloud run, but without access restriction. Now it should be available only for certain users.
I read https://cloud.google.com/run/docs/authenticating/end-users and also tried both
mentioned ways: Google-Sign-In and the "Identity Platform" tutorial.
If I understand correctly, you have to program the actual user handling yourself in both variants. For example, determining which email addresses have access to the application, etc.
I was looking for a declarative way where, ideally, I only maintain a list of permitted email addresses and the "cloud run application" is only "magically" linked to this. With the result that only these users get access to the web application. That doesn't seem possible?
Ideally, the actual application should not be changed at all and an upstream layer would take care of the authentication and authorization, possibly in conjunction with the "Identiy Platform".
Best regards and any hint is welcome
Thomas
Let me add some sugar to this to better understand all these.
A Cloud Run application is packaged by you, you maintain the source code, if this is a website, placing a login button and handling authentication is your job to accomplish.
A Cloud Run system which is running all this on a hardware, it doesn't "look into" or handles your application code outside of the "code". Simply put it doesn't know if it's a Java or Python code and how to handle authentication out of the box for you - but read further.
If you require a simple way to authorize look into API Gateway it can be placed "before" Cloud Run. It might not be exactly your use case. These exists only for "API" designed services.
That upstream layer you need is the managed Identity platform, but the CODE should be assembled by you and deployed inside your Cloud Run service. The code will be the UI driven part, the authorization logic is handled by the Identity Platform so it reduces the amount of development time.
Your users would sign up using a dedicated registration page, and sign in by entering their emails and passwords. Identity Platform offers a pre-built authentication UI you can use for these pages, or you can build your own. You might also want to support additional sign-in methods, such as social providers (like Facebook or Google), phone numbers, OIDC, or SAML.
Look into some of the advanced examples to get a feeling how authorization can be customized further: Only allowing registration from a specific domain you could reuse one of these samples to maintain that shortlist of users that you mentioned.
In addition to #Pentium10's answer, you can also make all users authenticate to your app somewhat forcibly. (Imagine you're building an internal portal for your company, or an /admin panel for your app that only certain users/groups can access.)
This sort of use case can be achieved by placing Cloud Identity-Aware Proxy (IAP) in front of your Cloud Run service. That way, all requests go through this proxy that validates the caller. This is not like Identity Platform in the sense that visitors don't create accounts on your website (they use existing Google accounts or other IdPs like ActiveDirectory, or whatever you configure on IAP).
I have a little tutorial at https://github.com/ahmetb/cloud-run-iap-terraform-demo/ since IAP+Cloud Run integration is still not GA and therefore not fully documented.
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).
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.