ASP.NET Core Google Auth for multi-tenant apps with single callback url? - asp.net-core

I am building a multi-tenant asp.net core app based where tenants are selected by host names. So tenant1.example.com, tenant2.example.com, ..., and so on.
Also, I'm using Google authentication using the default Google auth handler in asp.net core services.AddAuthentication(...).AddGoogle(...)
It's working great, except that Google doesn't support wildcard callback URLs. So every time I add a new tenant, I have to configure my Google app with a new callback URL to reflect the new host: tenant1.example.com/signin-google, tenant2.example.com, ..., and so on.
The asp.net core Google handler lets you specify the callback path, but not the URL. I plan to overwrite the handler to have the callback URL always go to a redirector url hosted on the naked domain, example.com/redirect-google (I'll be careful about open redirects), and have that redirect to the appropriate sub-domain to complete the authentication.
Has anyone done this before? Anyone see a problem with this approach?

You are right that the authentication system does not allow you to further modify the host for the OAuth redirect URI. This is mostly done to make the system host name agnostic, which is a common pattern that is used throughout the framework (basically every URL generation is based on the current context).
As a workaround, what you could do is set up your own authentication handler for the Google scheme. You can actually inherit from the GoogleHandler and override the BuildChallengeUrl. That method is called to actually build the challenge URI of the authentication provider. It gets passed the redirectUrl which is the callback route of the OAuthHandler (the thing you cannot change the host name of).
So by overriding the method, you can simply change the redirectUrl that gets passed and replace it with the general URL that you want to use.
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
{
return base.BuildChallengeUrl(properties, "https://example.com/redirect-google");
}
When you do that, you will just have to replace the GoogleHandler in the DI config:
services.AddTransient<GoogleHandler, ReplacedGoogleHandler>();

Related

Sending xAPI statement to a web application instead of LRS

I have an xAPI content made by storyline I want for the statement to be sent to a webapp instead of the LRS.
this webapp is developped using laravel, and user should be authenticated with email and password to use it.
what I did to send the statement to this app:
1.in the webapp I created an API endpoint route that use POST method.
2.in the xAPI wrapper I changed the endpoint in the configuration to the route I made in the webapp.
const conf = {
"endpoint":"here I added my api endpoint route of the webapp",
"auth":"Basic " + toBase64(""),
}
now whith any interaction with the content where a statement should be sent the request making cors error like in the picture down, I think this is authentication error, how can I add my authentication credentials to the xAPI wrapper?
Your non-LRS LRS is probably not handling preflight requests which are necessary for CORS handling. Most common LRSs will handle those requests appropriately since they expect to be accessed from additional origins. See https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests
Also note that you'll likely run into issues unless you also handle state requests.
Additionally unless you are requesting the credentials from the user during runtime then hard coding the credentials into the package isn't a great idea from a security perspective.

How to update options in Restsharp v107 (RestClientOptoins)

I'm not finding any RestClient method to update its options, what I need to do is for example disable FollowRedirects for certain requests.
How do I do the following but with v107?
client.FollowRedirects = false;
Background: maybe a separate issue but current problem is that RestSharp is not following a redirect URL to Okta from a Location header of a response, it goes to the main Client URL instead. That is why I've decided to disable redirects to try following the redirect manually.
Most if not all of the properties in RestClientOptions are used to configure the HttpMessageHandler instance wrapped by RestClient. As each RestClient instance wraps a single HttpClient (and its handler), those options cannot be changed. It works the same way as configuring HttpClient, where you cannot change the AllowAutoRedirects property of the handler once it's configured.
That's why the documentation suggests using a specifically configured RestClient instance per remote API. Normally, the API uses a single convention and configuration requirement.
I have seen that some authentication endpoints require redirects, but most of the time the RestClient instance used to get the authorization token is not the one used to access the API itself with the retrieved token. So, the solution would be to have a separate instance for that purpose. Normally, it's only used once to get the token, then you can dispose it and reuse the token.
I keep posting the authenticator example from the docs https://restsharp.dev/usage.html#authenticator
Concerning RestSharp not following redirects properly, it's not what RestSharp does as it doesn't compose or execute HTTP calls physically. It just wraps HttpClient.

Passport basic authentication only for API requests

I'm writing an express/node/angular application. When the client-side angular controllers need some data, they request it from the server using an endpoint that returns JSON.
This endpoint is behind some passport.authenticate('local') middleware, however this endpoint is exactly what we need for a public API.
Our API uses a passport.authenticate('basic') (basic http auth).
I'm trying to find a way to use the same URL for both, but I don't want users to my site who aren't logged in to see an http authentication window. I somehow need to tell "is this an API request, or an xhr request from the site"
For example, I want the following URL to work for a locally-authenticated user (would have been authenticated via a /login route) or for an API user:
app.get('/api/v1/tasks', passport.authenticate('basic'), tasks.list);
The only alternative I know of that works is splitting these into two different URLs, one for the site to use internally, and one for the public API. Maybe that's a better strategy for security/organization anyway?

Sitecore with LDAP - authenticate programmatically

I am creating an app inside Sitecore and I only want it available to the users via a direct URL. I want the authentication to occur against LDAP. I tried going directly to the app and let it redirect to the auto login page and redirect me to the app but it didn't do it. Instead it took me to the Sitecore login page.
I'm wondering if it is possible for me to write some code to auto authenticate a LDAP user and redirect to the app page. I want the user to never see the login page or Sitecore desktop or any of the Sitecore screens other than that one app.
Thanks
We accomplished something similar by combining the AD module with some custom code in the Global.asax. Below are a few lines that might be helpful. You'll likely need a bunch of logic to check if the user is already logged in, and whether they are accessing a path you want to auto-login for.
NOTE: Make sure windows authentication is enabled in IIS.
protected void Session_Start(object sender, EventArgs e){
// The user from Windows Authentication in IIS
var user = Context.Request.ServerVariables["LOGON_USER"];
//Log the user in
bool success = Sitecore.Security.Authentication.AuthenticationManager.Provider.Login(user, false);
}
You'll note that the sample I provided goes directly to the provider. You can also call Login at the AuthenticationManager class, and this will also do some other work with cache. In my case, I was trying to bypass that.
UPDATE (2017-06-29):
In newer versions of Sitecore it is not recommended to make changes to the Global.asax. Unfortunately, there is no equivalent pipeline in Sitecore. You can attempt to use httpRequestBegin (where the UserResolver processor is) or httpRequestProcessed, but these will fire on every single request.
One alternative (credit to #Mark Cassidy on SlackChat) is to use the Initialize pipeline and in that processor register to the session start event.
It is possible yes, a quick Google search turned up these:
http://www.nehemiahj.com/2013/01/how-to-enable-single-sign-on-in-sitecore.html
based on the AD Module from Sitecore
http://sdn.sitecore.net/SDN5/Products/AD/AD11/Documentation.aspx
That should give you a good place to start from.

How to execute a function immediately after authentication

My question is this: With a web application, after performing a login authentication for a protected resource, how can I run some sort of function (in this case, I want to run a function to initialize some user-dependent session-scope variables) BEFORE the web-app redirects to the protected resource.
I am programming a web application using servlets and JSP's, all within the struts framework. I believe I have followed the correct JAAS or J2EE standards for security.
In other words, I have configured the web-application via the web.xml file to redirect all requests for protected material to a login form that asks the user for login information. It then submits to j_Security_check which performs the authentication and authorization before redirecting the user to the protected materials.
So, I need to run a function sometime just after the web application says "yes, this person is who they say they are" and before the web application shoves them at where they want to go.
Hope you can help me. Thanks in advance.
If you use serverside sessions:
Create a servlet filter
In the filter: See if an attribute in the session has been set
If not: Check if user is authenticated and perform your operation if they are. Then set the attribute in the session
Thus, the operation will be executed only once.