I have an API that uses another API (example google calendar API) which is authenticated with OAuth 2.
httpRequest => MyApi under test => uses external Oauth2 enabled API
If the "Oauth2 enabled API" were using HTTP basic authentication, I could just hardcode the username and password somewhere to test the application —using the username and password of a test user created in the external APP that exposes the API that I am using.
As with Oauth2 we require the user to consent (the user is usually redirected to a web page) to ask them for consent to the app to access their data through the API.
I just want to create simple Integration Test: For example, my API creates an event in the google calendar, then deletes it for cleanup, but without human intervention.
Is this possible and how?
If you're developing an API, then your tests should be against that API only. You are not responsible for the work done in the external Oauth2 API, the author of that API is. Only test your own code.
Which means, you should find a way to mock out the calls to the external API if possible.
I've been wondering about the best way to do this myself.
So far I've found a few of options:
Use the password grant type, to authenticate as a user. This is apparently no longer recommended as per best practices, but that's for end-users. Not for testing.
Use the client_credentials grant type, to authenticate as the app itself. The problem with this is that if your test depends on being able to retrieve user data, the app won't have any associated to itself, unless you manipulate it beforehand.
Request a refresh_token, to re-authenticate as a previously authenticated user. This is done by requesting the offline_access scope. A user will have to do the first authentication, get a refresh token and provision the test script with it. The script then must be able to keep updating itself with a fresh refresh token each time it runs. And if the refresh token should expire before the next run, human intervention will be required again.
Use the device_code grant type to poll for end-user consent elsewhere. This is like what YouTube uses to pair your SmartTV, whereby you start the login on your SmartTV and consent to it with a pairing code on your mobile device. Here, human intervention is required as well for the consent, at least the first time, and then again should the consent expire.
Related
I'm currently planning on making an online scheduler in Blazor Webassembly (NET Core 3.1). As I've written intranet applications most of the time, I'm kind of concerned about the security aspects of the web api that the client will consume.
Currently, we're issuing JWT Tokens from the Backend with the username and the validity of the token in hours to the client and store the said token in the local storage of the browser. Since the token can be accessed by the user and the claims can be extracted from it, is there anything I have to be aware of? The token then is set as the DefaultRequestHeader of the HttpClient after the user has logged in. A cusotm Middleware then validates the token and sets the username in a scoped service if the user is authenticated.
The users (customers and employees) are stored in a database which is not publicly accessible. There is no option to register a user via the website. Users can create appointments in multiple locations of the company (not at the same time/day) but how do you restrict a user from consuming an api endpoint for one location but not for the other? Since claims can be manipulated I'm really not that confident in writing the accessible locations into the jwt.
Some actions also required to be executed in the four eyes principal, e.g. a second user needs to login (30 seconds validity with a refresh if possoible) in order to confirm the action. Are there existing mechanisms which are capable of handling such a thing?
Any advice, sources or thoughts are welcome. Feel free to ask for more details if necessary.
You could look at these posts, they helped me: https://chrissainty.com/securing-your-blazor-apps-authentication-with-clientside-blazor-using-webapi-aspnet-core-identity/
I am working on a .net MVC and web API project and using active directory to authenticate users to API, on authentication, a code is being returned from AD and I have to exchange the code to obtain a token and use that token to call the API, the question is why is the code returned and why do I have to exchange it for the token? can I directly obtain a token?
This is all because of security reasons.
OAuth 2.0 wanted to meet these two criteria:
All developers will not have an SSL enabled server and you should allow them to use non-HTTPS redirect URI
You don't want hackers to be able to steal access/refresh tokens by intercepting requests.
Since the Authorization Code grant has the extra step of exchanging the authorization code for the access token, it provides an additional layer of security not present in the Implicit grant type.
According to Nate Barbettini we want the extra step of exchanging the authentication code for the access token, because the authentication code can be used in the front channel (less secure), and the access token can be used in the back channel (more secure).
Thus, the security benefit is that the access token isn't exposed to the browser, and thus cannot be intercepted/grabbed from a browser. We trust the web server more, which communicates via back channels. The access token, which is secret, can then remain on the web server, and not be exposed to the browser (i.e. front channels).
For more information, watch this fantastic video:
OAuth 2.0 and OpenID Connect (in plain English) https://youtu.be/996OiexHze0?t=26m30s (Start 26 mins)
Your question isn't really specific to Azure AD, and is more about the OAuth flow and why it is used.
The flow seems a bit complex, and well, it is, but there are reasons for all the things it does.
I encourage you to use authorization code flow instead of other approaches.
It has many advantages:
Your app will never see the user's password
The user cannot see your app's client secret
The user cannot see your app's access tokens (and neither can a man-in-the-middle attacker)
You get a refresh token that you can use to get new tokens whenever needed (you do need to specify the offline_access scope for this though)
The user can go through multi-factor authentication, federated authentication with ADFS etc., and your app doesn't need to care about that
Alternative flows and their downsides:
Implicit flow
Gives you a token directly without the code exchange
There is no refresh token
Mainly used in Single Page Apps, where refresh is done using a hidden iframe, but that depends on the user's session remaining active
If you use this outside a SPA, you can't really refresh the token, requiring the user to login again every hour
User can see and take your app's access tokens
Client credentials flow
Instead of accessing the API as a user, you access it as the app itself
Some APIs do not support this approach and require you to make calls on behalf of a user
This doesn't allow you to authenticate a user
Application permissions are needed to use this flow, which usually give very broad access to the entire organization
The upside of this flow is that it is very simple
Resource Owner Password Credentials flow
Do not use this flow
HTTP request to token endpoint with app + user credentials
Exposes user password to your app (!)
Does not work if user has MFA, expired password etc.
I have searched all over for an answer to this, and not found anything that seems to answer my question. Which feels like it should be an easy one (but clearly isn't).
I have an API which authenticates using a token. This token I generate from my application - more specifically, I have a new Token Generation web call that will return a token. Currently, I pass in a cookie with the user and password information, and it uses this to identify who I am and what I should be allowed to do. This is all working absolutely fine and hunky-dory.
I am achieving this process by making the Token Generation use OWIN Cookie Authentication, which means that the cookie is read and the Identity is set. I am then able to use this identity to confirm whether the user is allowed to access the system.
What I now want to do is replace this Cookie Authentication process by authenticating against a Windows User (everything is windows based, and this will be an option so non-windows users can still use the cookie authentication route). But I cannot discover how to straightforwardly do this.
Note that I don't actually need to validate that the user is genuine or refer back to the AD at all. If you provide a windows user that matches a user in the system, you can log in.
So how can I - easily - get the requesting user into the Identity Name? Or is this not possible?
If you are looking for information on the current user accessing your program, assuming the program is running on the user's machine and is windows based, you can simply query windows for the user's username or any other publicly available information about the user.
Refer to https://learn.microsoft.com/en-us/dotnet/api/system.environment?view=netframework-4.8 for information on the Enviroment class and what it's features are.
If you could provide some code or further clarity I could help you further.
Google API OAuth 2.0 servcie Account C# ( drive api)
I am only targeting ONE Service Account.
I am looking in authenticating to a service account.
following this example:
Google example
As far I can understand, the token is permanent not 1h like other authentication type. Yet there is no mention of the token in the code.
Do I have to store this token? or do I have to request it every time I want to create the service, using the certificate?
Is the "service" creation code the same as described every time I need it. Or is this just for the very first time I request access to this account?
As I've commented, the article "Using Google Drive API with C#" part 1 and part 2, shows how to store the refresh token and use it to authenticate in the name of app.
It's also warning about the limitations of the service account, in many cases "useless" as you said.
Here's another one implementation of IDataStore.
Hope that help you! =)
Google offers a few options for authenticating users. One of them is Service Accounts which provides more secure communication between your app and Google server while authenticating users.
Normally, if you use Google oAuth library in server side, a shared key is used to authenticate user and to get a token which includes access_token, toke type, refresh_token, expire time. In this case, user should give you permissions.
However, when you use Service account, user is not involved and service account is used for authentication. In this case, in first time, you should use Service Account to get a token and store it in your DB. That way, you will be able to use it next time while sending API calls. And of course, for security reasons, this access token will expire. In this case, you will use refresh_token which returns when you get token for the first time. With using refresh token, you will be able get a new access token.
I want to write an application which can update an twitter status of an certain twitter account.
The user has to log in to twitter.
I want to make this application with Twitterizer, but since it uses oAuth, the user needs to go to the twitter website to tell twitter that my application is granted access to the user's twitter account.
Because I want to make a very simple twitter application for people who are not really even expert with computers, I don't really want that process.
Is there any option to automate the web UI of the oAuth process? Or an option to don't use that web UI?
The purpose of OAuth is to ensure that the user is aware that they are granting a 3rd party access to their account. If OAuth allowed the process to be automated, it would undermine the very reason it exists.
One way around asking the user to copy/paste a PIN, is to use the HttpListener class to create a simple webservice that runs on the client's computer. You can create it long enough to listen for the user to be directed back to the callback url and capture the values needed. I've demonstrated this technique on my blog.
Just as commentary: to say "but since [Twitterizer] uses oAuth" insinuates that it was my design decision (I'm Twitterizer author), where it is really the security protocol required to interact with the Twitter API. Every Twitter library requires the use of OAuth.