cross application (authentication) issue using react.js, spring, tomcat 8 - ajax

My team is rewriting an existing web application that has a react.js front-end and springboot backend. In addition, The original (legacy) app is written in java (tomcat 8 & struts) and that will continue to be used for some parts of the site until a later date when we will complete the rewrite. All 3 endpoints are on the same domain in the following format: react.js (mysite.mydomain.com), spring (mysiteapp.mydomain.com), and legacy (mysite.mydomain.com/old). All 3 apps are hosted on the same server, but the application urls all route through our F5, so nothing is pointing to localhost. We did this to use the same SSL certificate across the three apps. The new and legacy apps use the same database. We are trying to make cross app calls between the new and old app. When we make the cross app calls, we want the user session to be maintained between them without them having to log in twice. We have not been able to get this to work. In our latest attempt to authenticate the user to both apps simultaneously, we are using ajax to sign the user into legacy with the same credentials. We are getting the following error back from the legacy tomcat application: HTTP Status 403 Invalid CSRF token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'. The server understood the request but refuses to authorize it. We are stumped at this point and out of ideas. Code can be provided on request, but we are looking for the best approach to how to implement this and not as much locked on this path described above.

Related

Can Azure API Management be used as a pass through for an ASP.NET MVC website that also contains APIs?

I have a single ASP.NET MVC app - website and API controllers. I'd like to use Azure API Management to manage these APIs but retain the same URL so that it is seamless for our consumers. We have a custom domain setup on the app service for this web app that is currently used to serve up both the site and APIs(e.g. Website: xyz.com, APIs: xyz.com/api1, xyz.com/api2, etc.). Also we use AAD for auth. and have the redirect URI setup to the custom domain(xyz.com). Everything works great at present.
The issue arises after we configure API Management to expose our APIs and potentially use it as a passthrough. In order to ensure that the URLs remain the same after API Management is introduced we set the custom domain to be on the API Management instance itself and removed it from the app. service. This is how our current setup looks -->
User hits xyz.com and the request proceeds as follows -> Traffic Manager -> APIM(xyz.com) -> App Service(xxx.azurewebsites.net)
After that last point above, AAD auth. should kick in and once it has the access token after successful auth. it should redirect the user and the page should load. But it doesn't. Instead we get a blank page and if we refresh it, then and only then does it proceed to auth. and load the page.
We have tried setting our redirect URI to both the custom domain(xyz.com) as well as the base app service name that Azure generated(xxx.azurewebsites.net).
Directly hitting the API urls specifically(e.g. xyz.com/api1) works fine. It goes through APIM and responds as expected. The only problem is that the website doesn't load as outlined above.
The moment we take APIM out of the equation, and set the custom domain back on the app service again, everything works as expected.
I'm trying to figure out if we've misconfigured our assets for this scenario somehow or if APIM doesn't support pass through for the website in this manner. Any thoughts/suggestions here would be much appreciated!
Wow, that was a lot of text.
Ok, let's see:
Visitors -> Traffic manager -> APIM -> backend (your website) - ok got it.
this is like a common way of using APIM, and it should work. However, maybe your policies are not set up correctly?
Have you built your product/API/Operations? Do you see requests coming from APIM hitting your site? What responses are you getting?
Now, of course, you will need to define and set up APIM (products, APIs, and every operation) to pass it throw to your backend. This means if you (as a visitor) need to list all products, you would need to go through the APIM operation (sed GetProducts ). Your request will be passed through the Inbound policy(adjust and build the request if needed), pass it to the backend( to your website with custom APIs), and the response will be sent back from the backend back to the visitor.
Now to this: to protect your Web API Backend in APIM, you could use OAuth 2.0 authorization with Azure AD:
big picture overview:
Register an application (for your backend) in Azure AD to represent the API
Register another Application (the client) in Azure AD to represent a client app that will call your API
And I guess this is the one for you grant permissions to allow the client app to call the backend app
And, of course, add the validate-jwt policy to validate the OAuth token for every incoming request
Read om on this here https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad

How do I secure a Web API with Azure AD B2C

I have a Angular application and a separate Web API solution built with .NET Core. I have successfully setup authentication with Azure AD B2C. I am able to login to the angular application. However I would like to secure one of my Web API calls. i.e. http://localhost/Profile/GetProfile. The trouble is that I'm able to query this url successfully even when not logged in.
I used code from the sample application in github and strangely I get 401 not authorized when trying to make my api call from my ClientApp. However, I am able to open that url successfully in a new tab (outside of my application). I am trying to achieve the opposite of this. i.e. it should 401 from a browser but 200 from my ClientApp. What am I doing wrong?
BTW the sample application throws a unhandled exception when trying to navigate to the todo menu item.
The trouble is that I'm able to query this url successfully even when
not logged in.
This is because the cache is still there after you successfully log in. Once you've used browser privacy mode, you'll need to log in again.
And is these screenshots below what you want to achieve? You can decode token in this.Whether the requested token is successful does not match the api endpoint.If so,please check your client app (API perssions) & server app(Expose an API).
401 from a browser
2.200 from my ClientApp.(Here's a microsoft graph me/endpoint demo.)

SSO with ADFS using WS Federation working fine on localhost but not on server

We want to implement SSO in our multiple application
eg : abc.domain.com/app1 and abc.domain.com/app2.
We have configured ADFS on our server. WE have used WS federation authentication. Our both app are aware of claim based authentication.
Scenario we want to achieve,
1. Make login on app abc.domain.com/app1 using ADFS WS federation authentication.
2. We have successfully authenticated in this domain.
3. Now make request on abc.domain.com/app2. It should be login automatically in this app.
Actioned:
Both app URLs are added on relying party trust in ADFS.
We have added Endpoint URL of 1st app abc.domain.com/app1
Both app refer same ADFS metadata URL.
We have achieved this in our local environment. In local system these two different app are running on different port
1. localhost:44313
2. localhost:44330
When we make successfully login on localhost:44313 and request on localhost:44330 then user also authenticated for this app as well and displayed as logged in.
This scenario is not working fine for the live environment. Our live URL structure is same as mentioned above (abc.domain.com/app1, abc.domain.com/app2) but it's not working there.
Any help would be appreciated!
What errors do you see in the event log?
If you have two different apps, you need two different RP on ADFS.
Also you need to run both on https.
Do you have https on your live environment?

Web api 2 - windows + client cert auth - is it possible?

I currently have an asp.net web api 2 site hosted in IIS secured with windows authentication. A requirement has now come in for us to support client certificate authentication in addition to windows, and I'm struggling to find out:
- if this is possible at all
- if there are any working examples available
I thought might be able to add an additional owin middleware or messagehandler or filter, but can't see any existing ones that do this specifically for windows rather than just relying on IIS. I know thinktecture identitymodel can do client cert, but not sure if the two can be combined?
Example of forms +win that i thought might be similar is here https://techblog.dorogin.com/mixed-windows-forms-authentication-for-ajax-single-page-application-e4aaaac0424a
Right so I managed to figure it out. Thankfully, if a controller returns a 401, IIS automatically adds the negotiate/ntlm headers, so if a user is on a windows browser, it will then automatically authenticate as usual. So with that in mind, to keep windows auth working, I:
updated the site in both IIS and VS to allow anonymous AND windows auth
added the [AuthorizeAttribute] as a global action filter (which causes the 401 to be returned if the user is not authenticated by the time they hit the filter)
To get client certificate auth working, I used the magnificent Thinktecture.IdentityModel library, which allowed me to add only one line to my Startup.cs file (we're using OWIN so this was easy)
app.UseClientCertificateAuthentication();
See https://github.com/IdentityModel/Thinktecture.IdentityModel/blob/master/samples/OWIN/AuthenticationTansformation/KatanaAuthentication/Startup.cs for an example

401 Unauthorized when authenticating with Google for hybrid applications

I want to use native applications and a web server to get refresh tokens to use for some operations (on google drive). Client ids and secrets have been generated for both the native and the web application using the Google developer console.
I'm trying to generate authcodes from the native applications and exchange them from the web server for access/refresh tokens using a script heavily inspired from the java example. The main difference is that there is two GoogleAuthorizationCodeFlow (they represent the native and server parts):
One using the native application's id and secret and used for generating the authorization code.
One using the web application id and secret and used to exchange the authorization code for credentials.
Such procedure does however result into a 401 Unauthorized exception.
When using for both GoogleAuthorizationCodeFlows the same credentials, either the creds of the native application or the web application ones, the process succeed and returns a refresh token.
How can I use the authorization code from a native application on a web application to generate access tokens? Is there a way to use the web application id and secret to exchange the authorization code or must be procedure be finished using the same credentials used for generating the token?
The reason that it is not working is that Authentication is linked to the client id and client secret.
When a user authenticates they are authenticating that client id / client secret pair. You cant just take the Refresh token or the Authentication code and use it with a different client id and secret they wont match and it wont work and you will get a 401 Unauthorized exception.
your on the right track with
How can I use the authorization code from a native application on a
web application to generate access tokens?
What you need to do is create Client ID for native application just one and use the client id and client secret for both your native application and your web application.
Web vs Native
The only real difference between a Client ID for native application and a Client ID for web application is the Redirect URI. The Redirect URI just tells the Authentication server where to return the authentication to. In the case of a website that's easy its the web page where you handle the code most of the time this is the same ip address. In the case of a native application there is no way to know this so the server sends the information back to the requesting ip. Beyond that there is really not difference, except maybe that Google likes to know if its a website or a installed application running the code maybe. So you can use a native client id on a web application the server will just return it to where ever it asked.
Security
There are probably some security considerations with using a native one on a web application, I guess someone could potentoaly get a hold of it and send info with your client id. TBH I find the chance of this limited.

Resources