How do I set up a local test SAML2.0 Identity Provider? - node.js

As a Service Provider (SP) I have written a node.js service to processes SAML2.0 Assertions. I would now like to test this code.
I am aware that I can use various cloud-based services to act as my test Identity Provider (IdP) however these require that my new, untested SP end-points be made public.
Currently I am simply POSTing a hand-crafted SAML2.0 Assertion to my SP end-point but I want a more realistic test, especially the ability to test SP initiated SSO.
Therefore I believe I need to have a local IdP running on my development machine so I can, for now, keep all my testing local and sand-boxed.
Can you recommend a way forward for me?

You actually do not need to publish your endpoints in order to be able to use a public IDP.
All communication between the SP and IDP is either done through your browser (which of course needs to be able to access both your local SP and public IDP), or your SP calls IDP (when using HTTP-Artifact profile). But in usual situations IDP never directly calls SP, which means that SP can be running locally without a publicly accessible URL.
One of the public IDPs which can be configured in this way is SSO Circle.
In case you would still like to run an IDP locally, Shibboleth is probably your easiest bet.

There is an open Idp that will reply to any AuthnRequest available for free at https://stubidp.sustainsys.com. It will allow you to set the Subject NameId you want in a simple form and then reply back to the SP. If you want to set up your own instance, the source of the stubidp is available at https://github.com/Sustainsys/Saml2.
Disclosure notice: I'm the author of the stubidp, but I won't make any money out of anyone using it, it's provided entirely as a free service.

Another option is https://github.com/mcguinness/saml-idp. It's straight-forward and quick to setup for local testing (it's a node server). I successfully used it to implement some full end-to-end SAML SSO tests using cypress.
We have a .net core app, and I basically just run node server.js on startup if running in development environment. I redirect output of the node server to our .net core web app's output, so we can see the SAML requests/responses right alongside our app's logs. Works really well.

Agree with Shibboleth - others are SimpleSAMLphp and (if you have Windows Server) then perhaps ADFS.
If you go the cloud route, Azure Active Directory is another option - albeit that it only currently supports SP Initiated.

Related

How to add Azure Authentication to my current web application which is using API as well?

So my project has got a two asp.net projects. One is for showing date(User Interface) and the another one is API(for background processes like login, database calls and etc.). Right now my app has Username and Password feature to login. I have setup a startup class in my API which authenticates the user and pass the user token. Now I want to add a feature to login through Azure portal.
Can anyone suggest me a good practice in this situation? Like I don't want to change my code and just add a feature. Should I make changes in API or Web or Both? Meanwhile I was reading about expose api in app registration. Will it be appropriate to use it just for login purposes?
Azure AD supports OAuth2, OIDC and SAML. See more information here. It is probably best to introduce the mechanism through the API first, since it would apply to the frontend as well (though slight modifications may be required there as well).

Restrict Access to my Azure Web App only to my web job?

I am trying to restrict access to my azure web app only to one of my web jobs.
Can I use IP Restrictions to achieve this.
To achieve this type of restriction, IP Based restriction will not be of use for the following reasons:
There might be other applications(owned by you, in case of standard above plans, or other customer apps in case of free/shared planes) that will be running on the same server and those also will have access to your web app.
There is no fixed outbound IP for your web job as it might be moving to different instances (in case you have multiple instances in your app)
A quick and easy solution for your original problem is:
Implement either BASIC Auth (username/pwd) or Bearer token Auth on your web app side.
From your web Job (in the Invoke-WebRequest) pass either the username/pwd or auth token based on whichever auth mode you choose.
Here are a few links that discuss implementing Basic Auth for Azure Web Apps and how to call such an app via PowerShell:
How to use the script (Invoke-WebRequest -Uri) to pass a parameter to your page
Use Invoke-WebRequest with a username and password for basic authentication on the GitHub API
How to use a C# code in the Web App to authenticate the request parameter
https://learn.microsoft.com/en-us/rest/api/datacatalog/authenticate-a-client-app
Since with basic authentication, credentials are passed in plaintext an can be easily decoded, we recommend that the web job calls the WebApp URL over SSL. Also, Basic Auth is one of the simplest authentication mechanisms, there are other more complex authentication schemes available too that you might want to explore.

How to safely call Azure Function with function level authorization in Xamarin mobile app?

I'm making an iOS/Android app using Xamarin (not Xamarin.Forms, just regular Xamarin). I'm using the shared library set up rather than PCL. I want my app to call an Azure function but I'm unsure of the safest/best way to handle this. I have it set to "Function" for the "Authorization level". The test URL includes the "?code=..." portion in it. I was under the impression that if I put that in my C# code with the "code" value exposed that it was considered a bad idea from a security perspective.
I'm lost as to the safest/best way to deal with this. I've read that setting it in app.config is also a bad idea. I found some references for a web app that suggest using the connection strings that are available in the azure portal, but since this isn't a web app, I'm unsure of how I'd actually retrieve those values in my code (or if that's even possible).
So how would you suggest I handle setting the value for "code" so that I can call my function and avoid a security problem?
UPDATE: Providing more info as per request:
I'm using MSAL to authenticate my users with a B2C active directory. I already have that part working and have received a token authenticating the user.
I also just now enabled authentication in my functions.
I was under the impression that to call my function from my mobile client I had to make a new HttpRequestMessage. I'm unsure of then what I'd place in it to pass my token along.
Just to make sure I understand, your concern is about embedding secrets (the ?code=XXX value) in your iOS/Android app, correct? If so, yes, this is generally considered bad security practice. It's best to assume that anyone who can download your app will have the ability to discover these secrets and use them any way they want.
The recommended way to authenticate with a backend service, such as Azure Functions, from a mobile device is to use interactive authentication - i.e. some kind of OAuth flow. You can build it yourself, or you can use the built-in functionality of Azure Functions and Azure App Service to help you (Azure Functions is built on top of App Service). Here is a resource which might be useful:
https://learn.microsoft.com/en-us/azure/app-service/app-service-authentication-overview
https://contos.io/working-with-identity-in-an-azure-function-1a981e10b900#.vcjit3ntw
The API Key (code) is indeed not meant to be used by clients you distribute externally, so it shouldn't be used by your mobile app.
The most straight forward option here would be to use the built in App Service Authentication features with Azure Functions and implement an authentication flow in your app, which would allow you to securely authenticate the user.
Sharing more information about your scenario may help identify alternatives.

Azure AD Login/logout implementation for Spring cloud microservices

I want to implement login and logout functionality and retrive user details like username and user role using Azure Active Directory.
We are using Docker to deploy Spring cloud microservices project on Azure cloud. Could you please suggest me steps to get user details?
Do we need to secure all microservices edge points using Spring cloud OAuth2 security using JWT or just we can secure one web microservice ? Do I need any permission ,specific user roles to implement this?
You can find Azure's documentation about OAuth 2.0 support for AAD here
https://learn.microsoft.com/en-us/azure/active-directory/active-directory-protocols-oauth-code
I've got an application that's using OAuth 2.0 with a different Authentication Server, and I'm about to see if I can use AAD as the Authentication Server. But, whatever ends up being your Auth Server, the rest of the application should be the same...
The Auth Server handles the log in (typically as a Single-Sign On pattern)
The Auth Server will return a Json Web Token (at some point, depending on the Grant Type being used to retrieve it)
The JWT should be included in each subsequent request to ensure the caller has authorization
From a Spring perspective, you'll need at least a SSO Client (denoted by the #EnableOAuthSSO annotation). If everything in hosted by that process, you'll need that JWT to call subsequent methods. If you have processes hosted in other processes, it's likely you'll want them secured as well. Using the #EnableResourceServer annotation will configure Spring Security to look for the JWT, just not attempt to retrieve one if the request does not have it.
Unless the endpoint is meant to be publicly accessible, you will want to secure it. Of course, I really don't know the context of your application, so this statement is purely an uninformed opinion based on zero knowledge of what you're trying to do with your application. Take it for what it's worth.
EDIT
This has become a little more complex than I originally thought. I have been able to write some code to dynamically retrieve the public key from Microsoft in order to validate the returned JWT.
But, the main issue is the fact the Azure AD supports Open Id Connect when acting as an Identity/Authentication Server. And, at the moment, spring-security-oauth2 doesn't support Open Id Connect.
I was able to make some small changes to the spring code, but I did ask the question to the Spring group and they are actively working on adding support for Open Id Connect. They hope to have a release two months (ish?).
For the short term, the oauth2 support doesn't support Open Id Connect. Given this is the protocol used by AAD, the current version of oauth2 won't work with AAD. That said, I will be happy to wait for the official support which shouldn't be too long.

WebApi secured by Azure Active Directory called from JavaScript

I have the following scenario:
1.- A web api project in Azure, that I want to secure using Azure AD (I don't mind Token, cookie, whatever, as far as it meets the entire scenario)
2.- An Azure web site in asp.net MVC, also secured by Azure AD. This website has to call the web api controller with SSO (I'm using same Azure AD in the entire scenario)
3.- Some JavaScript code running in a page in SharePoint Online, also calling the web api controller in any secure way (The Office 365 tenant is also using same Azure AD). If you don't know about SharePoint, let's say I have an SPA project where I can only use Javascript and html (no server side code).
Following some of the MS Azure AD samples and some blogs from Vittorio Bertocci I'm able to get the points 1 and 2 working fine, using OWIN and Oppen ID connect. However, seems impossible to achieve point 3. As I'm inside a page in SharePoint Online, I can only use javascript, and not any server side code. I'd like to get a valid token for the current user, that is already logged in SP, and remember that SP uses same Azure AD that web api site.
Can I call the Azure AD and get a valid token, just from client code?
I'm open to any possible solution. I can do whatever in the web api project. If you are thinking in a SharePoint app with an appPart, and the appPart calls the web api from server side code, I agree that will work, but it's an option that is not allowed at the moment :(
Many thanks.
I have similar needs. While waiting for a Microsoft sponsored solution we’re working on the following approach.
3) in Your solution (i.e. HTML page with JavaScript, hosted in SharePoint Online and running in Browser) will call Services in 1) (i.e. Web Api Service layer in Azure).
In Our case we only want to validate that the calls made from SharePoint Online (via users browser, i.e. JavaScript) originate from a correct Office 365 / SharePoint Online user in our tenant.
We are opting out of using the App Model as we only want some simple HTML / JavaScript pages in our Intranet and don’t want App Webs. The Web Api server side code is kind of our “Web Part” code behind.
Change to the solution after trying it out and having workable code:
The auth cookies are ReadOnly and cannot be used. Instead we have registered one metod in our service layer as App in SharePoint Online (via appregnew.aspx). That methods url (e.g. https://cloudservice.customer.com/api/authentication/token) is registered as App start page in the app manifest and is deployed to a site Collection.
Now we can call our App via https://customer.sharepoint.com/sites/devassets/_layouts/15/appredirect.aspx?instance_id={GUID} i a jQuery ajax call and parse the result. AppRedirect sends the correct SPAuthToken which we use in our service endpoint (i.e. App start page) to call back to SharePoint and check context.Web.CurrentUser. User email is then stored in Table Storage with a generated Token which we send back to the caller (i.e. the jQuery ajax call to app redirect).
That token is then used in all other service layer calls in order to be sure of who is calling our service layer and in some cases perform authorization in our service layer.
Note, You can use the same approach in order to store Refresh and AccessToken in your client and provide that in all calls to your service from your client and use those tokens in order to do App Calls back to SharePoint. This enables HTML UI in SharePoint host webs and server code using user context in Azure service layer.
To follow up, ADAL.js has recently been released, and the ability to use CORS with O365 APIs was recently added, enabling a scenario for script clients to communicate with services protected by Azure AD, such as your Web API.
http://www.andrewconnell.com/blog/adal-js-cors-with-o365-apis-files-sharepoint
UPDATE 2018:
This is now supported by SharePoint Online and the SPFx development model, and officially documented, for instance here
Consume enterprise APIs secured with Azure AD in SharePoint Framework
Being said that the work done meanwhile by Vittorio, Kirk, and their teams, but extending that also to Andrew that has delivered great samples, is awesome; that doesn't really fully reply the original question because one of the requirements is to don't run the component as Add-in Part.
If you try to use ADAL JS (which starts its own OAuth flow) hosting that directly in a SP page, that's not going to work, or anyway you can expect a weird behavior for the user (cause of client redirects happening on the browser).
The solution proposed by Peter Karpinski is interesting, and will work matching the requirements in the original question, but requires quite some complexity and additional management/resources.
This recent article provides an alternative solution similar to Peter's one, but requiring less 'extras' and somewhat simpler, also reusing user's SP identity.
Consuming Azure Hosted Web API from SharePoint Online using JavaScript and Office 365 identities
and doesn't either require the use of ADAL on the client side and the implementation of custom security provider / token issuer on the server side.
The identity (cookie) will be passed via properly handling CORS (documentation) on both sides.
However, as you can read in my comments to that blog, this won't work normally with IE due to its security zone implementation. You'll have to be sure you have control on IE security zones on the clients, or have an alternative solution specific for IE.
As of today AAD does not support the OAuth2 implicit flow (or OpenId Connect variants) hence you can't obtain a token from AAD using a user-agent (browser), regardless of whether you hit the wire handcrafting the protocol or using a library.
However keep an eye on future announcements, as this is an important scenario for us!
HTH
Cheers,
V.
update we now support the implicit flow on our server, and we released a library for helping you consume the new feature: http://www.cloudidentity.com/blog/2015/02/19/introducing-adal-js-v1/
Thank youi for r your patience!
The fact that you say you can use only HTML/JS let me guess you're having a SharePoint-hosted App.
Azure AD Authentication Library (ADAL) doesn't provide yet in this moment support for HTML5.
I've been looking since a while (almost one year) on how to implement something as you say; but I couldn't find any working solution, which doesn't make use also of some 'code-behind'.
I'd suggest you then to move to a Provider-hosted App, where you'll be able to have some C# code, and make use of ADAL to retrieve and reuse the OAuth token.
Also, I think is worth to look at this documentation page:
Choose patterns for developing and hosting your app for SharePoint
at section Match your hosting pattern with your development goals
thanks for your help.
Well, it's not a SP-Hosted App, but it's same scenario. It's just a SP page in SP Online, so I can only use JS code like in a SP-hosted app.
As I said in my question, I agree the Provider hosted app is likely the right (or at least, the unique) solution, but that means to build and app, deploy it, and add teh appPart manually to the page (is not easy to package in a WSP). So, this solution is quite hard, when you only want to make some AJAX calls and show some data.
However, after all that I've seen, I think we can't do anything else. I'm gonna wait some more days to see if someone know any weird workarround that could work, and if not, I'll mark your answer as valid.
Thanks again!

Resources