AAD Configured REST API consumption in another AAD Configured REST API - azure-active-directory

Good Morning !!
We have a scenario where a client app hitting a intermediary service (REST - AAD Configured) , will be inturn routed to another Service Endpoint (REST - AAD Configured). While doing so, we are successful in gettting accesstoken at client layer after hit to intermediary service. Now, Intermediary Service should consume an API of another service which is AAD Configured. For doing so, we have made use of BootstrapContext - for which we have got just token but not security token. We did try by making use of same token to consume, but in vain that wasn't helpful.
Exception while consuming REST Service from Intermediary service is nothing but " AAD Login Page HTML " and status is 200 OK.
Kindly Suggest where we missed a piece and suggest needful.
P.S : I have added Intermediary Service in azure portal to client app to have access for consumption and Intermediary service has access to consume REST Service which needs to be consumed. Also, in all layers we are using latest nu-get package of ADAL.
Regards,
Jagadeesh

It sounds like you secured your API using the wrong authentication mechanism - unauthenticated or improperly authenticated API calls should never result in redirects or HTML pages. Also, the bootstrap token you receive is for the first service. The intermediate service should refuse that token as its audience is incorrect. See https://azure.microsoft.com/en-us/documentation/samples/active-directory-dotnet-webapi-onbehalfof/ for the proper pattern.

Related

Microsoft Graph - OAuth2.0 flow for React client and spring-boot backend

I am building a React-based SPA that communicates with a spring-boot backend via a REST API. I need the user to be able to log into their Microsoft account on the browser client (the SPA) and I need the backend service (spring-boot app) to be able to query Microsoft's Graph API on behalf of that user.
After reading up on the Oauth2 flows, the authorization code flow (not the PKCE flow, just the regular authorization code flow) seems the most appropriate. The browser client could let the user log into their Microsoft account, retrieve an authorization code, and send the authorization code to our backend service via HTTP request. The backend service (which is trusted and can safely store a client secret) can then request an access token, make requests to the Graph API directly (meaning that the SPA would never need to make any requests to the Graph API), and silently refresh the token as needed.
However, I cannot see any examples of anyone using this flow to access Microsoft's Graph API.
Looking at Microsoft's documentation, it seems like they recommend using the on-behalf-of flow. But this flow requires the browser client to request an access token and then use that to communicate with the backend service (which in turn can communicate with the Graph API). It doesn't make sense to me why the access token cannot be requested on the backend using a client secret. Wouldn't this be a more secure and preferred method than having the client retrieve the access token, as is done in the on-behalf-of flow?
The Oauth2.0 site, recommends that SPAs should either use the authorization code with PKE or the implicit flow, but I do not see an option to use the standard authentication code flow for SPAs. Should I take this as an indication that SPAs should not be using the standard authorization code flow as I described earlier?
Despite not finding a clear-cut example of the standard authorization code flow in Microsoft's documentation for a react frontend + java backend, I tried to go about doing this myself. However, using the #microsoft/mgt-react and #microsoft/mgt-element libraries to do this are not straight forward. For example, the #microsoft/mgt-element notion of a Provider supports a call to retrieve an access token, but doesn't clearly expose the authorization code. If I wanted to do the authorization code flow described earlier, it seems like I would need to use raw HTTP requests, which I know is not a recommended way of accomplishing this.
Summarizing my questions:
What OAuth2.0 flow should I be using: 1) authorization code (access token is retrieved by backend service using client secret), 2)
authorization code with PKE (access token is retrieved by client), or
3) on-behalf-of flow (access token is retrieved by client, seems to be an extension of PKE flow)?
If using the on-behalf-of flow, does the SPA just include the access token in the header (marked as 'bearer') and the backend service just
includes that same header to query the Graph API, or does the backend
service need to request another token before querying the Graph API?
Agree with #ch4mp to call graph api directly in SPA if it's allowed. If not, then I recommend you using on-behalf-flow or client credential flow based on your requirement.
Let's come back to your requirement -- call ms graph api in a springboot api project. First, let's see one of the graph api getting user api. You can see permission types here: Delegated which means call graph api on behalf of the user, Application which means calling api on behalf of the application(your spingboot api project) itself. If you want to call api behalf of the user, then you have to use on-behalf-of flow. This is because the api project which will be considered as a daemon application, so the project itself doesn't have a UI page to let users enter username/password to sign in and get authenticated.
You can certainly use ROPC flow which have to pass the username/password to api but I really think it unsafe, so I don't recommend.
If it's not necessary for you to call graph api on behalf of user, you can certainly take client credential flow into consideration. But pls note here, application type api permission is a "large" api permission which always have name like User.ReadWrite.All, Mail.ReadWrite.All and it always means the application can not only query user information but also be able to modify user information.
If you want to use on-behalf-flow, then you may review this answer and it explained the whole progress...
I would use authorization-code flow (with PKCE) to get an access-token and then refresh-token flow to "maintain" this token, both from client.
Authorizing the request to your resource-server with this token only makes sense if Microsoft authorization-server is your main authorization-server. Otherwise (user also logged in with an authorization-server of your own or not using OAuth2 betwean React and backend), you can still send Microsoft access-token in request body.
In any case, when issuing requests in the name of the user from the backend, do as you suggest: just set the access-token sent by the client as Bearer Authorization header (token is retrieved either from Spring security context or request body). Backend fetches a new access-token (using client-credentials flow) when issuing requests in its own name (without the context of a user).
Side note: have you considered calling Microsoft API directly from React client? If you don't have to store the result of that call on your resource-server (i.e. call graph API to display data and store only what user selected from that data), that would save quite some latency on the client and costs (network and CPU) on the backend.

React SSO using SAML without web server

I have a web app developed using Create-react-app
I host it on IIS, the IIS only response to load the app, there is no server side logic on it (no Express or any other web server)
The app is using a RESTful API on the same IIS, it is out of my control (I cannot make change).
Now one of my client request to add SAML SSO to our app.
I would like to know:
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
For my case, I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Could any one give me some React implement SAML SSO tutorial or article for reference?
Thanks for any help, any information or suggestion are welcome!
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
I assume the client wants to authenticate the users using their internal IdP. So your application is the SP. But you will have to define different token service (details below).
With SPA (a single-page-applications) I see the problem, in SAML the user is redirected or posted away from the SAML request and SAML response.
I have a login page to enter id/pw, post them to API server Login endpoint to authenticate and get back a JWT token. After that we use that token in API calls for authentication
The API services are using a JWT token issued based on the provided username/password. I'd recommend to extend the token service (or use a different service) to issue a JWT token based on the provided SAML response - a token swap service. In many OAuth implementations it's called SAML grant type.
I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Usually after the authentication the user is redirected or posted to the SAML ACS endpoint URL, where the server can create sort of session (cookie, parameters, token, ..) and the user is redirected to a URL returned the web page with the session information.
If you are using an SPA, you could use a popup window or SAML with redirect (not with post), where the page could read the SAML response parameters (assertion, signature, ..) and use them in the token swap service mentioned above.
When processing the SAML response, try to use some mature, known, out-of-box libraries, it's a security service and not doing it properly may cause security weaknesses. But you need to do that on the server side, as at the end you need the JWT token consumed by the APIs.

Is this user authentication process reasonable?

I've been developing RESTful API server communicating with cross-platform clients such as Android, iOS, Web browser, and so on.
When a user login successfully by username and password, this server issue an access token(JWT, 5 minutes) and a refresh token(GUID, 20 days).
When we develop Android client app communicating with server, we just can store this tokens in mobile device and I believe it will not be a problem in terms of security( using SharedPreferences).
But when it comes to Web browsers, (React App) I had to tackle where to store these tokens. Finally, I decided HttpOnly Cookie, because I can manage easily CSRF attacks rather than XSS.
Soon, I doubt this is a typical design. For example, web browser users cannot logout whenever they want. So I determinate change the wrapper server(Node.js) between the React app and the RESTful API server.
In my second design, the React App and the wrapper server authenticate session-cookie model, using passport.js for exmaple. And when the wrapper recognize the request is authenticated, then the wrapper issue a short term access token(1 minute JWT) and reorganize the request by inserting the access token just issued in the header sent to the RESTful API server.
Is this reasonable process? Thank you in advance.
You could simplify your solution by removing the JWT access token altogether. The refresh token could be used as a session id. Every time a client issues an API call to the server the session id is sent in an HTTP header, so you can check if the request is legitimate.
Your approach of using a JWT token with a short expiration time is ok, but it brings some complexity to your system. In my opinion this approach is best suited for systems where you have an authentication service and a resource owner service. So the client would request an access token to the authentication service and use that token to communicate with the resource owner service. Then the resource owner can check the validity of the access token by just checking whether the signature matches the authentication service's.
I hope this helps you, let me know if I'm missing something.

Angular JS SPA using LDAP authentication

I'm writing an AngularJS SPA application which calls Rest full web service. Back-end is being written on JAX-RS, deployed on Tomcat 7. I'm using HTTPS, SSL for transferring data from SPA to JAX-RS
requirements
I have to make LDAP authentication. (I will send username & password to web service and it should make authentication)
I have to do user's session management (because, when authenticated user sends request to web service, user doesn't have to authenticate again)
problems
I think there are two options for doing LDAP authentication:
Make LDAP authentication using core java http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ldap.html
Use Spring security (I'm not familiar with it and not sure if it's possible. I think I should send username & password to rest service. Rest service will have spring security library injected and it'll be possible to use authentication functionality. Am I right?)
Manage user sessions. Once user is authenticated, it should be saved somewhere, so that user can do operations until its logon is not expired.
How can I do it?
Which way should I choose? How should I make LDAP authenticating and session management?
Can anyone give any suggestion or example links?
So,
LDAP Authentication using JNDI works just fine, you could also use the neat UnboundID LDAP Java API. A simple LDAP Bind example can be found here: https://code.google.com/p/ldap-sample-code/source/browse/trunk/src/main/java/samplecode/bind/SimpleBindExample.java .
Note also that you could use a Node.JS module as your backend, the Passport.JS Authentication framework for example, provides lots of features/capabilities relative to authentication and Federation (i.e., do things like 'Login with Google', etc...). See: passportjs.org.
On the Angular/frontend side,your best bet is to use a JWT token. It's all explained in detail with examples here: http://code.tutsplus.com/tutorials/token-based-authentication-with-angularjs-nodejs--cms-22543.
In essence:
your backend Authentication REST should return a JWT Token in the response, once the user successfully binds to LDAP. This Token would contain some user data, and should be encrypted (see link above).
Your Angular App should set that token as a cookie on the client Browser ("set-cookie" response header) upon successful login (so in the Controller of your Login view).
The Client will then present that cookie/JWT Token on every request it makes to your app.
Your app will then need to validate the token presented on every request (in the controller of your SPA). You may also want to add the user authentication data to your $scope so you can use it in your view.
Hope it helps...

How to accomplish google oauth authentication using nancy api and angularjs?

I have been looking around for this issue and haven't found anything yet.
I want to create a webapp that requests offline access to google api, and the my main concern is that I'm using angular as a front-end and I'm consuming a api created in nancy.
I have been able to get access but only for a couple of hours, but I need the user to grand offline access to the app because it's going to have a task running every amount of time needed.
Have anyone already accomplish this one? Tried? Experience? I've tried to call the google oauth api to request the token but it returns 405 method not allowed.
You can use Simpleauthentication, which has Nancy specific NuGet package. Just follow the instruction to set ip SimpleAuthentication in a Nancy app.
I've never used nancy. But in general, your OAUTH concerns should be handled server-side. The user validates against the google oauth, that google oauth flow returns to the back-end server, and the back-end server gives up a key, cookie, or something like that, which your front-end now uses in its request.
That's at least how I handle it. I use a token-based scheme for all my $http requests from my back-end API, which returns 401 if there's no valid token on the request and 403 if there is a token, but that token doesn't authorize that resource. I stuck a httpProvider interceptor in angular that, in the event of a 401, initiates client-side login flow.
Specifically, the token just is a randomly generated series of bits turned into hexadecimal, and then I stash it in redis as a key whose value is the user_id associated with this login.
Of course all of this requires a real https stack to be secure, since I'm just pushing what amount to plain-text one-time keys around, but that's about all you can do about that.

Resources