How to use SAML authentication in a mobile application? - angularjs

I'm trying to understand how an saml authentication flow could work in a mobile environment where the client (AngularJS based), api server (Node & passport based), and idp exist on different domains.
From what I've gathered the general practice is to have the server return a 401 to the client if there's no authentication present (i.e. the client didn't include a bearer token in the request). The client understands that a 401 response indicates to open up the login endpoint on the server. When the login endpoint is opened it makes a passport call to the auth provider (which redirects the user to the auth provider's site) and supplies a callback URL. When the user authenticates, the auth provider redirects to the provided callback URL, which allows the server to retrieve information from the auth provider's response and construct a token of some sort (e.g. JWT) that can be used by the client (i.e. included in the headers) when making REST calls to identify itself.
My question is: How does the client get the token from the server? Because we're in a redirect-based authentication flow, I can't just return token from the callback function; that would just display the token in the browser without handing it off of to the client. Does the server just issue a 302 redirect pointing back to the client domain and include the authentication token in a header? Maybe I should not redirect from the client to the server in the first place and instead window.open() and use window.opener.postMessage or is that too old fashioned/mobile-unfriendly?
This question talks about authentication against a SAML IDP, but I'm interested in getting more details specifically about that last bullet point and how it would work with an AngularJS-based client.
Many examples I've seen online are either a single domain using OAuth/SAML (passport-saml-example), which avoids the issue of having the client exist on a separate domain, or use two domains with basic authentication, which avoids the issue of redirecting to some third party for authentication, but I'm having trouble finding good examples that uses all the bits and pieces I'm trying to work with.
This blog post seems very close to what I'm trying to accomplish (see googleSignInCallback) and uses a 302 redirect like I imagined but that solution relies on explicitly knowing the client URL to redirect to, which seems like it could be problematic if I wanted to support multiple client types (i.e. Native applications) in the future.

Eventually I was able to work together a solution by having my application open a browser window (Cordova's InAppBrowser) to a SAML-enabled application, have that application complete the normal SAML flow, and then that SAML-enabled application generated a JWT. My mobile application was then able to extract the JWT string from the browser window with the InAppBrowser's executeScript functionality. Then I could pass that JWT string along to my API server, which was able to validate the JWT is properly signed and trusted.
After I implemented my solution I saw that there was similar functionality available on github:
https://github.com/feedhenry-templates/saml-service
https://github.com/feedhenry-templates/saml-cloud-app
https://github.com/feedhenry-templates/saml-cordova-app
Hopefully this helps anyone else trying to deal with this issue!

Related

Authorization and authentication in web application with ASP.NET Core backend and React frontend?

I have a web application, where the frontend is built with react.js and typescript and the backend is build with ASP.NET Core 3.1 and connected to a SQL Server. The SQL Server is used for saving data, which I can enter in the frontend.
Now I want to implement a custom authentication system, where I can protect different endpoints with an authorization. I know there are several ways to go for, but I don't want to use a service / library, where a user could login with his google account for example.
Jwt seems in my Opinion a good way to go here, but I really don't understand the whole system.
This article helped me already a lot: Implementing authentication and authorization with React hooks, .NET Core Web API, and SQL Server .After reading this, I don't understand the relationship between logging in and how my backend knows, that a user is logged in (for protecting my endpoints).
Of course I already read many articles about authentication and authorization for ASP.NET Core. I've read about different services like:
Auth0 (seems not a good idea, because you can login with google etc.)
IdentityUI (seems good, I've seen a few youtube tutorials but they are all using another project structure, where the frontend and backend isn't separated. So they are using the razor pages like Login.cshtml, but I don't want to render any pages in the backend, only in the frontend)
For authorization for my controller in the backend, I planned to use the following:
[Authorize] // to protect endpoint
[HttpGet]
public async Task<IEnumerable<>> GetData()
{
// some code
}
But as I already said: I don't know / understand how my backend knows if a user is logged in (and how to check it).
Could somebody provide me an appropriate tutorial or an article, where is explained, how to manage authorization and authentication for frontend and backend? Or maybe somebody knows, how to use the IdentityUI with a frontend build with react + typescript and a backend, which shouldn't render any pages.
Thanks for your attention :)
Well... for detailed flow how they work, here is RFC 6749, this is a pretty comprehensive collection of knowledge related to the topic and the easiest approach would be wiki page in general.
But to simplify the process, just get to know these things:
What is JWT
Jwt just a string that was generated by some algorithm from a public/private key pair(don't even care how it works, just give it a key pair, some lib on every language would do the rest). This JWT often contain all the information that needed to specify who the user is(big word right ? but actually, userId is enough for simple case).
It contain 3 different parts Header, Payload and Signature, and the string assured it cannot be interrupted(or just modify it as we wish, and the validation process would failed).
Further detail here.
What happen on server side?
The most basically flow was send user, password to server for validate who we are and our account exists. Then, server side would take some necessary info out of it to generate the JWT token. The server which generate JWT token was normally refer to Identity Provider.
Then that token was send back to client, and client save it somewhere for later use.
Client side use token to request other resource
Normally, Identity Provider would provide a .wellknow endpoint that contain all necessary info for other resources to gather for validation process.
Now, client side send a http request to these resources with the JWT token. They use info gathered from .wellknow endpoint to validate was the JWT valid. If it is, we are who we claim we are, authentication process success.
The end.
Over-simplyfied flow imagination in your specific case
React Client => Request login => Identity Provider => Jwt Token send back => React client save it somewhere.
React Client => Request some resource over http with the JWT token => Resource server validate it (through info from .wellknow endpoint) => Authentication success or fail => normal process => send response back to client.

How authorization code flow works in single page applications?

Hi I am exploring some of the authentication and authorization flows with respect to azure active directory. I was using previously oath implicit flow in single page application. After spending time in reading microsoft documentation, I have understood following with respect to implicit flow.
Implicit Flow:
Single page javacript application uses implicit flow to get obtain access token from azure active directory. It directly calls token endpoint to obtain the token so this makes implicit flow less secure.
Authorization Folw in .Net Web application
Whenever we use .Net core web mvc application with authorization code flow, first call will happen in browser to authorization endpoint to get code. In browser we could see the request made to authorization end point. In request url I will pass response type as code then client id and redirect ui. Here first handshake take place between browser and authorization end point. This handshake returns code to the redirect uri. Next part, application has to make POST request to token endpoint to get access token. Code received in first step I will send in token request. In this request I will include client secrete also, redierct uri also. But whenever I make first GET request to authorization endpoint I will not pass client secrete. This is because Its not good to expose secrete in browser. So in second post request I will include client secrete also. Once I get access token I will add it in api request header to make secured call to apis.
This is the authorization code flow flavor I have understood with respect to .Net core web application. now I have another flavor of authorization code with respect to single page application.
Authorization Code Flow in React Web App
I have SPA react application which uses MSAL library. I have cloned sample application from github https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/tree/main/3-Authorization-II/1-call-api/SPA.
Whenever I run this application, and sign in first call will happen as below
https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=https://login.microsoftonline.com/c5ffa990-7e0a-4bf6-6c04-79ab98e05931/oauth2/v2.0/authorize
I am trying to understand this request. I have query string appended to the url authorization_endpoint=https://login.microsoftonline.com/c5ffa990-7e0a-4bf6-6c04-79ab98e05931/oauth2/v2.0/authorize so this may be used to return the code from authorization server.
Immediately next call will happen https://login.microsoftonline.com/c5ffa990-7e0a-4bf6-6c04-79ab98e05931/oauth2/v2.0/token
to get access token and in request in FormData section I could see following parameters
client_d, redirect_uri,scope,code
In code I see some code value hopefully received from authorization endpoint. anyway this api returned me access_token.
Now coming to conclusion, In .Net core web application and React SPA application both places I am using authorization code flow.
In .Net core authorization code flow I am making use of client secrete whenever trying to obtain access token. All this happen in server side in secure manner. In react also I am using Authorization code flow but I am not using Client secrete anywhere.
In react app also I am making two requests one for authorization endpoint to get code and another to get token. All this I can see in browser itself but then How can I consider this is as secure?
In .Net web app and react app both apps making use of authorization code flow but it behaves independently depends on the type of application.
After going through several documents and videos over the internet I concluded myself as
When Authorization code flow used with server side web apps like .Net core MVC, It makes use of client_secrete to get access token and this call will happen in server side so client secrete not exposed through browser to the users
When Authorization flow used SPA applications without server side support, first it will make call to get authorization code then It will make post request to get access token WITHOUT client_secrete.The only way the authorization code grant with no client secret can be secure is by using the “state” parameter and restricting the redirect URL to trusted clients.
So I am concluding myself as when we use server side web app with authorization code flow we can make use of client secrete but in case of SPA we are not making use of client_secrete.
I have understood above concepts and explained what I understood and also I listed the confusions I got after implementing 2 flavors of authorization code flow in web app and spa app. can someone help me If my understanding is correct or not, If my understanding is wrong, where exactly I understood wrong? Can anyone help me with respect to this. Any help would be greatly appreciated. Thanks
Authcode flow is an OAuth 2.0 workflow, you can use it in any kind of client (Web/mobile/SPA).
Clients should be using MSAL library to communicate with AAD/B2C with PKCE which is used to secure authorization code grants via Proof Key for Code Exchange (code_challenge) with S256 encryption.
Authcode Grant Flow spec:
If you are using B2C, your entry endpoint is:
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=code
&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob
&response_mode=query
&scope=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6%20offline_access
&state=arbitrary_data_you_can_receive_in_the_response
&code_challenge=YTFjNjI1OWYzMzA3MTI4ZDY2Njg5M2RkNmVjNDE5YmEyZGRhOGYyM2IzNjdmZWFhMTQ1ODg3NDcxY2Nl
&code_challenge_method=S256
that will display the SignIn-SignUp-Social Login Form. Just navigate to this URL with you App ClientId registered inside B2C.
You also can take a look to the custom policies starter pack to adapt your workflow to your needs (claims).
If you change response_type=code for response_type=id_token you will get a Token that can be used to authenticate against your restricted resources (API's) after all login process.
Or you can use a second call to the token endpoint to get it.
Token endpoint:
POST https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6&scope=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...&redirect_uri=urn:ietf:wg:oauth:2.0:oob&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
code=XXXXXXXXXXXXX parameter is the access_code returned from first GET request.
Solutions to this is to switch to implicit flow, where there is no need of exchanging code for access token. But keeping access token in web application still vulnerable as this can be exposed using XSS or similar kind of attacks.
Other best practice is https://curity.io/resources/learn/the-token-handler-pattern/

Client Side Rendering and API Security [duplicate]

I'm developing the restful web app that using some popular web framework on the backend, say (rails, sinatra, flask, express.js). Ideally, I want to develop client side with Backbone.js. How do I let only my javascript client side interact with those API calls? I don't want those API calls to be public and be called by curl or simply by entering the link on browser.
As a first principle, if your API is consumed by your JS client, you have to assume, that it is public: A simple JS debugger puts an attacker into a position, where he can send a byte-for-byte identical request from a tool of his choice.
That said, if I read your question correctly, this is not, what you want to avoid: What you really don't want to happen is, that your API is consumed (on a regular basis) without your JS client being involved. Here are some ideas on how to if not enforce, then at least encourage using your client:
I am sure, your API has some sort of authentication field (e.g. Hash computed on the client). If not, take a look at This SO question. Make sure you use a salt (or even API key) that is given to your JS client on a session basis (a.o.t. hardcoded). This way, an unauthorized consumer of your API is forced into much more work.
On loading the JS client, remember some HTTP headers (user agent comes to mind) and the IP address and ask for reauthentication if they change, employing blacklists for the usual suspects. This forces an attacker to do his homework more thoroughly again.
On the server side, remember the last few API calls, and before allowing another one, check if business logic allows for the new one right now: This denies an attacker the ability to concentrate many of his sessions into one session with your server: In combination with the other measures, this will make an abuser easy detectable.
I might not have said that with the necessary clarity: I consider it impossible to make it completely impossible for an abuser to consume your service, but you can make it so hard, it might not be worth the hassle.
You should implement some sort of authentication system. One good way to handle this is to define some expected header variables. For example, you can have an auth/login API call that returns a session token. Subsequent calls to your API will expect a session token to be set in an HTTP header variable with a specific name like 'your-api-token'.
Alternatively many systems create access tokens or keys that are expected (like youtube, facebook or twitter) using some sort of api account system. In those cases, your client would have to store these in some manner in the client.
Then it's simply a matter of adding a check for the session into your REST framework and throwing an exception. If at all possible the status code (to be restful) would be a 401 error.
There's an open standard now called "JSON Web Token",
see https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for
creating tokens that assert some number of claims. For example, a
server could generate a token that has the claim "logged in as admin"
and provide that to a client. The client could then use that token to
prove that they are logged in as admin. The tokens are signed by the
server's key, so the server is able to verify that the token is
legitimate. The tokens are designed to be compact, URL-safe and usable
especially in web browser single sign-on (SSO) context. JWT claims can
be typically used to pass identity of authenticated users between an
identity provider and a service provider, or any other type of claims
as required by business processes.[1][2] The tokens can also be
authenticated and encrypted.[3][4]
Set a SESSION var on the server when the client first loads your index.html (or backbone.js etc.)
Check this var on the server-side on every API call.
P.S. this is not a "security" solution!!! This is just to ease the load on your server so people don't abuse it or "hotlink" your API from other websites and apps.
Excuse me #MarkAmery and Eugene, but that is incorrect.
Your js+html (client) app running in the browser CAN be set up to exclude unauthorized direct calls to the API as follows:
First step: Set up the API to require authentication. The client must first authenticate itself via the server (or some other security server) for example asking the human user to provide the correct password.
Before authentication the calls to the API are not accepted.
During authentication a "token" is returned.
After authentication only API calls with the authentication "token" will be accepted.
Of course at this stage only authorized users who have the password can access the API, although if they are programmers debugging the app, they can access it directly for testing purposes.
Second step: Now set up an extra security API, that is to be called within a short limit of time after the client js+html app was initially requested from the server. This "callback" will tell the server that the client was downloaded successfully. Restrict your REST API calls to work only if the client was requested recently and successfully.
Now in order to use your API they must first download the client and actually run it in a browser. Only after successfully receiving the callback, and then user entry within a short frame of time, will the API accept calls.
So you do not have to worry that this may be an unauthorized user without credentials.
(The title of the question, 'How do I secure REST API calls', and from most of what you say, that is your major concern, and not the literal question of HOW your API is called, but rather BY WHOM, correct?)
Here's what I do:
Secure the API with an HTTP Header with calls such as X-APITOKEN:
Use session variables in PHP. Have a login system in place and save the user token in session variables.
Call JS code with Ajax to PHP and use the session variable with curl to call the API. That way, if the session variable is not set, it won't call and the PHP code contains the Access Token to the API.

Is it ok to pass OAuth access tokens to the Client

i'm still pretty new to web-development I worked myself through Web Development with Node and Express by Ethan Brown and currently i'm trying to get a good understanding for the examples given by Full-Stack React Projects by Shama Hoque.
Currently i'm trying to refactor a lot of things that used to be server-side-rendered to be handled in the React SPA client. One of these things includes a simple GitHub widget, my previous flow worked like this:
The client user authenticates with my server using a GitHub OAuth app.
The server stores the access Token returned to the callback in a database on the server.
The server makes calls to the GitHub API using the user access Token stored in the database.
The server processes the results, renders it in HTML and sends it to the client.
However I realized that there is also possibility to implement it like this.
The client user authenticates with my server using a GitHub OAuth app.
The server passes the access Token returned to the callback back to the client
The client makes calls to the GitHub API using the user access token obtained from the server.
The client processes the results and renders it apropiately.
As far as I understand there is no inherent security risk doing this(a malacious user could interecept the access token when the oAuth provider redirects to the callback either way) and both flows have their up and downsides (e.g. 2nd flow produces less load on the server but also sacrifices control). Since I'm new to this and I came up with the 2nd flow myself I wanna double check if this is something thats ok to be doing or I've missed something, if so, what did I miss? Is there any other major down or upsides i'm not considering?
What you've implemented is the OAuth Authorization Flow. In this flow, the client (aka the browser) never gets the access token. Only your webserver gets it. And thus the client cannot make calls to the resource server (github). Your webserver makes the calls on the client's behalf.
You say:
a malacious user could interecept the access token when the oAuth provider redirects to the callback either way
However, if you implement the flow correctly, this is not true. This is because once you authenticate with the resource server, it only gives the browser an authentication code. This code is just a temporary ticket that can be exchanged for an access token. However, to exchange a code for the access token, you have to know a client secret. Only your web server knows the secret. So your browser sends the code to your server, and your server calls the resource server (github) with the code + secret to get the token.
The second flow you describe is the OAuth Implicit Flow.
This flow is very much what you described: After the user authenticates with the resource server, the browser ends up with the access token and just calls the resource server directly.
Both flows are very common. The Implicit flow is slightly less secure because there is more opportunity for Bad Guys to get access to the token in the browser's memory (or local storage, or cookie storage). The Authorization Flow is a bit more secure because the token stays on your server, and you do not have to depend upon users to keep it secure.

Can someone explain HttpContext.Authentication.GetTokenAsync("access_token")

I have implemented an ASP.NET Core MVC Client using Hybrid flow, and I am wondering what the HttpContext.Authentication.GetTokenAsync("access_token") does.
If you need more background on my question:
The instructions for accessing an API from with an ASP.Net Core Client App Controller Action are generally as follows:
var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var response = await client.GetAsync("http://localhost:5001/api/stuff");
There is magic in httpContext.Authentication.GetTokenAsync("access_token") :-)
I am wondering what this function might be doing. Is it decrypting the access token from a cookie in the MVC App Domain? ... from the ID4 Domain?
I am sorry but I have been unable to find sufficient documentation on what this does or finding the cookie the access token may be in. I have looked here:
https://learn.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.authentication.authenticationtokenextensions
Does anyone know what it does? A link to more thorough documentation is a totally appreciated answer.
TU!
You can store arbitrary tokens in your authentication cookie in and that method simply returns one with a given name. Actually setting that would have happened during the sign in process. So in short, it comes from the authentication cookie for your client application and would typically be set at the point of sign in using IdSrv4.
It's a way for the client webapp to confirm separately whether the user really did authenticate with IdentityServer (the user comes to your webapp, the webapp forwards the user to IdentityServer for authentication). The id_token comes back with the user to your webapp in a browser cookie, basically when your webapp sees that id token, it does an independent check with IdentityServer, and if it represents a valid user authentication, you'll get an access token back. You can use that access token to get user claims from the userinfo endpoint.
After all of the above, you can take one of the claims and use it as a key for your application's roles/permissions.

Resources