snowflake sso connection using sqlalchemy does not work - snowflake-cloud-data-platform

i am trying to configure an sso connection in my python script.
here's my code:
import sqlalchemy
def get_snowflake_engine(warehouse="ETL", environment=None):
username = ‘userx#domainx.com'
account = ‘accountx
database = ‘dbx’
authenticator = 'externalbrowser'
return sqlalchemy.create_engine(
f"snowflake://{username}:#{account}/{database}?authenticator={authenticator}&warehouse={warehouse}"
)
engine = get_snowflake_engine(environment='production')
connection = engine.connect()
try:
result = connection.execute('SELECT NOW()').fetchall()
print(result)
finally:
connection.close()
engine.dispose()
i expect my browser to pop with an authorisation form (we use google for sso)
and i get a messeage on the terminal, but nothing happens on the browser:
Initiating login request with your identity provider. A browser window should have opened for you to complete the login. If you can't see it, check existing browser windows, or your OS settings. Press CTRL+C to abort and try again...
after a while i get an exception
any advice?
using MacOS, Pycharm
BTW i configured on DataGrip a connection using authenticator = 'externalbrowser' and it works as expected.
TIA

I had a similar problem, the connector logs showed that it was missing the AWS region in the connection URL (eu-west-1 in my case) so I fixed by adding:
...
region = 'eu-west-1'
...
return sqlalchemy.create_engine(
f"snowflake://{username}:#{account}.{region}/{database}?authenticator={authenticator}&warehouse={warehouse}"
)
This resulted in the browser authentication window opening in browser and the query returning successfully.

Related

DefaultAzureCredential Failing for console app after redirect to localhost -localhost sent invalid response

I am using DefaultCredential to connect to build configuration from azure keyvault.
var secretClient = new SecretClient(new Uri($"https://{keyvaultName}.vault.azure.net/"),
new DefaultAzureCredential(true)
);
IConfigurationRoot configuration = null;
configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.AddAzureKeyVault(secretClient, new PrefixKeyVaultSecretManager(environment))
.AddUserSecrets<Program>().Build();
This was working earlier but now it is failing with interactive browser authentication.
After selecting account, it is redirecting back to localhost and throwing error ("localhost sent an invalid response")
I am using "Azure.Identity" Version="1.4.1" . I also tried with latest beta package(1.5.0-beta.4).
Also Azure.Security.KeyVault.Secrets" Version="4.2.0"
I was getting a similar error from a Windows app using interactive AzureAD authentication. It turned out to be the result of the localhost domain appearing in my Edge (and Chrome) HSTS policy cache. The Azure AD signin flow was trying to redirect to http://localhost:61425/?code=.... But because I had been developing an unrelated ASP.NET application on my machine that used the HSTS middleware (i.e. called app.UseHsts) my browser was remembering that policy and forcing the AzureAD signin redirect to https://localhost:61425/?code=.... That switch from http to https broke the redirect handling in my Windows app.
The solution was to delete the localhost domain from the browser's list of domain security policies.
In edge, type this in the address bar: edge://net-internals/#hsts
In Chrome: chrome://net-internals/#hsts
See ERR_SSL_PROTOCOL_ERROR for localhost from Visual Studio debug
Check your application's redirect URI at Azure Portal. You can find it under Authentication on your application's page.
Set the redirect URI to https://login.microsoftonline.com/common/oauth2/nativeclient.
More information about redirect URIs: https://learn.microsoft.com/en-us/azure/active-directory/develop/reply-url

ERR_HTTP2_PROTOCOL_ERROR after authentication is done

I'm trying to use ITfoxtec.Identity.Saml2.MvcCore on a .NET Core 3.1 web application using an in-house IdP.
It works great on our test server (Windows Server 2012, hosted in the IIS) but I can't get it to work on any other server.
This is what happens:
The initial call to the website is correctly identified as a non authenticated call and the user is being sent to the IdP where the user logs in as usual. The SAML-token is then posted back to the web applications assertion consumer service where everything seems like it does what its supposed to, saml2AuthnResponse.Status has statuscode Saml2StatusCodes.Success and the logfile says "AuthenticationScheme: saml2 signed in". Then it reads the ReturnUrl-parameter and log something like "Executing RedirectResult" but then it just stops. Nothing in the logfile, nothing in the IIS-logs. The user is met by the message
This site can’t be reached
...
ERR_HTTP2_PROTOCOL_ERROR
In short, every controller that has the [Authorize]-attribute gives the ERR_HTTP2_PROTOCOL_ERROR-error. When I remove all [Authorize]-attributes the application works great, although without authentication.
I've also tried the example TestWebAppCore-application from ITfoxtec.Identity.Saml2's github-page and it gives the same error. It works on our 2012 test-server but nowhere else.
Any ideas that I can try?
I think you need to trace the calls to see the actual http request and responses send between the browser and server. I usually use Fiddler for tracing the requests/response. Remember to enable Fiddler for https tracing.
My first thought is that the problem can have something to do with cookies. But it is only a guess...
You might be on to something, we disabled http/2 on the server and was greeted instead by this message:
Bad Request - Request Too Long
HTTP Error 400. The size of the request headers is too long.
It uses 5 cookie-chunks for the SAML-data for a total of 19941 bytes which is a bit to much. I've tried to make the application save the sessiondata in classic session objects instead but I cant seem to get it to work.
This is what I added to StartUp.cs:
In ConfigureService:
services.AddMvc()
.AddSessionStateTempDataProvider();
services.AddSession(options =>
options.Cookie.IsEssential = true
);
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
In Configure:
app.UseSession();
But it still fills up the header with cookies. What am I doing wrong? Is there a another way to make the session cookies smaller?

ADFS vNext Client Authentication (WPF) (Windows Server 2016 Preview 3)

I have a Windows Server 2016 TechnicalPreview 3 with a configured ADFS vNext, as first client I have created an MVC Application as a ReplingPartyTrust.
The authentication with the ADFS work really well with the MVC Application.
Now to the problem: I have written a Native Application (WPF) which i want to authenticate against the ADFS.
The Steps i did are:
To inform the ADFS of my new WPF Client i ran the the following PowerShell Script:
Add-ADFSClient -ClientType Public -Name “MyClient” -ClientId “E1CF1107-FF90-4228-93BF-26052DD2C714” -RedirectUri “https://E1CF1107-FF90-4228-93BF-26052DD2C714/redir´”
To authenticate the client (Code-Wise) i used the following NuGet-Package:
Microsoft.IdentityModel.Clients.ActiveDirectory (3.5 (Alpha))
Then I wrote the following code:
string authority = "https://win2016preview.server.local/adfs/ls";
string resourceURI = "https://adfs.server.local/MyMVCApp";
string clientReturnURI = "https://e1cf1107-ff90-4228-93bf-26052dd2c714/redir";
string clientID = "E1CF1107-FF90-4228-93BF-26052DD2C714";
var ac = new AuthenticationContext(authority, false);
var ar = await ac.AcquireTokenAsync(resourceURI, clientID, new
Uri(clientReturnURI),
new PlatformParameters(PromptBehavior.Auto, new
WindowInteropHelper(this).Handle));
With this code, the client should authenticate at the ADFS (over OAuth i think) and prompt the user to enter his organisation credentials.
If i run the application this window appears:
I choose Yes (Ja) and the credential prompt opens. In the same time the following exception occures
In the event log if the server ADFS the following error message appears:
Microsoft.IdentityServer.Web.Protocols.OAuth.Exceptions.OAuthAuthorizationUnauthorizedClientException: MSIS9321: Received invalid OAuth request. The client 'E1CF1107-FF90-4228-93BF-26052DD2C714' is forbidden to access the resource 'https://adfs.server.local/MyMVCApp.
at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthAuthorization.OAuthAuthorizationRequestContext.ValidateCore()
at Microsoft.IdentityServer.Web.Protocols.ProtocolContext.Validate()
at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthAuthorization.OAuthAuthorizationProtocolHandler.GetRequiredPipelineBehaviors(ProtocolContext pContext)
at Microsoft.IdentityServer.Web.PassiveProtocolListener.GatherDeviceSecurityToken(ProtocolContext protocolContext, PassiveProtocolHandler protocolHandler)
at Microsoft.IdentityServer.Web.PassiveProtocolListener.OnGetContext(WrappedHttpListenerContext context)
As far as i can tell, the ADFS recognizes the Client Id and tries to authenticate it. But the ADFS rejects the Client.
Did i forget to configure something? The client should just prompt the user, which authenticates against the ADFS, so the client can habe the AuthenticationToken.
I hope you can follow me. Thank you in advance!
The solution is very simple :)
Add the property IssuanceAuthorizationRules (Add-ADFSRelyingPartyTrust )
-IssuanceAuthorizationRules '=> issue (Type = "http://schemas.microsoft.com/authorization/claims/permit" value = "true");'

Google AppEngine - Firewall Notification:Your access has been blocked by firewall policy 732

I have written a WebApp, which is deployed on Google AppEngine. I am trying to fetch a url in my app.. It shows the following error:
Firewall Notification - Your access has been blocked by firewall
policy 732. If you have any further concerns, please contact your
network administrator for more information.
This is how I am fetching the url.. Am I doing something wrong here?
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(REQUEST_TIME_OUT);
conn.setReadTimeout(REQUEST_TIME_OUT);
conn.setDoOutput(true);
int length = dataToBePost.length();
conn.setRequestProperty("Content-Length", (String.valueOf(length)));
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(dataToBePost);
wr.flush();
InputStream inStream = conn.getInputStream();
//using inStream now
NOTE: This is happening only when I deploy my app on Google AppEngine, and if I deploy my app on my local server, it works fine.
The url which I am trying to fetch is outside from Google Cloud/AppEngine network..
Is there any specific thing I have to do to make it work on AppEngine?
This is a Fortinet Firewall notification.
That mean that your administrator blocked you that website.
I don't think Google use Fortinet, they have their own technology. BTW that sound correct as you are able to connect to it when localhost, and your IT block certain connection, like this one.
Source: I have the same at work. Good luck!

OAuth2WebServerFlow works from localhost, but not from real AppEngine Instance

I'm using OAuth2WebServerFlow to get the User's Sheets credentials to use with the gdata/spreadsheets API. I'm having a really hard time diagnosing the problem because it works flawlessly when I run the application locally.
This is the snippet I'm using to get the authorization URL:
CLIENT_ID = 'my-id'
CLIENT_SECRET = 'my-secret'
SCOPE = 'https://spreadsheets.google.com/feeds'
flow_object = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, SCOPE, redirect_uri=self.REDIRECT_URL, access_type='online')
authorize_url = flow_object.step1_get_authorize_url()
Locally (using REDIRECT_URL = 'http://localhost:8080/this-path/')
this produces:
https://accounts.google.com/o/oauth2/auth?redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fthis-path%2F&scope=https%3A%2F%2Fspreadsheets.google.com%2Ffeeds&client_id=my-id&response_type=code&access_type=online
On the live App Engine application (using REDIRECT_URL = 'http://my-app.appspot.com/this-path/')
this produces:
https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fspreadsheets.google.com%2Ffeeds&redirect_uri=http%3A%2F%2Fmy-app.appspot.com%2Fthis-path%2F&response_type=code&client_id=my-id&access_type=online
The application configuration looks like:
CLIENT ID: my-id
EMAIL ADDRESS: my-id#developer.gserviceaccount.com
CLIENT SECRET: my-secret
REDIRECT URIS:
http://localhost:8080/
http://my-app.appspot.com
https://my-app.appspot.com
http://my-app.appspot.com/this-path
https://my-app.appspot.com/this-path
http://my-app.appspot.com/this-path/
https://my-app.appspot.com/this-path/
JAVASCRIPT ORIGINS
http://localhost:8080
http://my-app.appspot.com
Going to the locally generated version of the url I can successfully grant the application permission. But at the url generated by my live application I get a 401 that says "Error: disabled_client The OAuth client was disabled".
I feel like its probably just a configuration error. Maybe the fact that it works locally is just a red herring? Perhaps I would always be able to grant localhost these permissions? I'm genuinely out of ideas on this and any help would be appreciated.
In the application configuration, redirect URL should be like this http://localhost:8080/oauth2callback, as according to my understanding oauth2callback authorizes the token at the end of the flow. Refer to the document [1].
[1] OAUTH 2.0: https://developers.google.com/api-client-library/python/guide/aaa_oauth#OAuth2WebServerFlow

Resources