How to enable "remember me" with Sql Authentication Method ActiveDirectoryInteractive? - azure-active-directory

Use case: A native(.NET desktop) app that connects to Azure SQL Database using Azure Active Directory authentication.
Since .NET 4.7.2 there is new SqlAuthenticationMethod.ActiveDirectoryInteractive setting for opening a connection to DB. This setting results in a pop-up dialog for sign in, which works well.
E.g. Some documentation example here
Problem: Each time the desktop app is restarted - the sign-in popup appears again, asking for password again, which is frustrating for people who prefer "remember me on this PC" kind of behavior.
Is there a way to enable "remember me" in this scenario ? I didn't find anything in the documentation / web / SO ...
P.S. I assume I can implement it myself if I work with JWT tokens and not with ActiveDirectoryInteractive, but before I do that asking here.

I came across a Token Cache option from here.
Which eventually helps with the problem of sign-in popup upon each restart, due to caching the token.
Get the FilesBasedAdalV3TokenCache class and then provide it when initializing AuthenticationContext:
...
AuthenticationContext authContext = new AuthenticationContext(parameters.Authority, new FilesBasedAdalV3TokenCache(".\\Token.dat"));
...

Related

Sitecore - How to get User ID if the user was logged in using external identity provider (Salesforce SSO)

I have a little bit of problem with the authentication on Sitecore website. Basically there is a button on the navbar, and when user clicks on the button, it redirects the same user to Salesforce to log in (Implementation of SSO). Basically I am using Salesforce as a identity provider and Sitecore Website as a service provider. Now I have a question? When user is logged, how can I get the ID of that user.
Do users in Sitecore User Manager have the same ID as the users in Salesforce, or I can just get a email to identify the user?
P.S: Sorry if this is a really stupid question, but I am a begineer when it comes to making Sitecore websites and the SAML SSO. Thank you in advance
Stop with the Sitecore and Salesforce for a second, you'll need to cover some basics and click through the login process manually before you automate it.
You probably are using a "connected app" in Salesforce that includes OAuth2 config (consumer key also known as client id; a secret; a list of scopes telling what this app is allowed to do on behalf of this SF user; a list of allowed urls that can login using this consumer key and secret. Etc.) It might even have something about Canvas Apps at bottom of the page.
Next would be - who's logging in. A core Salesforce user or do you have Partner Community, Customer Community (recently rebranded to "Digital Experiences").
Open incognito window and go to https://openidconnect.herokuapp.com/
For login host leave as is if you have production user or test.salesforce.com if you go from sandbox (you can also use branded urls, mycompany--dev.my.salesforce.com etc). If you have a community user you'll have to change the url to whatever is the community base url, like https://dev-mycompany.cs123.force.com/mycommunity
Don't change anything else, click next, next, next. This will take you through OAuth2 "web server flow" (one of many ways to log in). You type the username/password to SF screen and go back to that herokuapp with "authorisation code". The app has few minutes to swap that code for actual final "access token" and couple other pieces of info. Final step in this wizard calls OpenId "userinfo" - returning some info about the user that logged in. That's where you could pull the email if needed (and if there are extra fields you'd like SF to return in this process that's configurable too)
Close that browser window. Check the "connected app" in SF. Open new incognito window, do same thing but this time put your url, consumer key and secret (you might have to edit the app in SF first to allow callbacks to https://openidconnect.herokuapp.com/callback).
So now you should have rough idea about whole login process. Your sitecore app probably does same thing, receives authorisation code and exchanges it for final token. At that point you have valid SF session ID you could use to call that "userinfo", run queries (if the app allowes API access, check the "scopes") etc.
I doubt the Sitecore developer created it all by hand, you probably have some Spring stuff like spring.security.oauth2.client... My Java days are long gone but if you get better at manual click-click-click through the flow you should be able to follow existing code?
It's a big topic and there are other ways to do it (other OAuth flows, sending info about the current user when you have external page embedded in SF as iframe, you'd need to read about "canvas apps")... but that's best guess based on info you provided. You might want to check some trailhead courses too like https://trailhead.salesforce.com/content/learn/projects/build-a-connected-app-for-api-integration/implement-the-oauth-20-web-server-authentication-flow
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_oauth_and_connected_apps.htm
https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/code_sample_auth_oauth.htm (Java but very hand-crafted raw HTTP, probably that Spring security is better)

Salesforce: How to automate report extraction as JSON/CSV

I am new to Salesforce, but am an experienced developer. I am provided a link to a Salesforce report, which mostly has the right filters (query). I would like to use an REST API to pull that information as CSV or JSON so that I can do further processing on it.
Here are my questions:
Do I need special permissions to make API calls? What are they?
Do I need to create an "app" with client-key & secret? Does my admin need to grant me permission for this too?
There are a lot of REST APIs from Salesforce, which one do I need to get the info from the report? Analytics?
How do I authenticate in code?
You'd have to work with the System Administrator on the security pieces. Anybody who knows how the company works, can all users see everything, is there Single Sign-On in place, how likely is the report to change...
You will need an user account to pull the data. You need to decide if it'll be some "system account" (you know username and password and have them stored in your app) or can it run for any user in this org. It might not matter much but reports are "fun". If there will be data visibility issues 6 months from now, you'll be asked to make sure the report shows only French data to French users etc... you can make it in report filters or have multiple reports - or you can just use current users access and then it's the sysadmin that has to set the sharing rules right. (would you ever think about packaging what you did and reusing in another SF instance? Making a mobile app out of it? Things like that, they may sound stupid now but will help you decide on best path)
The user (whether it'll be system account or human) needs Profile permissions like "API Enabled" + whatever else you'd need normally ("Run Reports" etc). If you're leaning towards doing it with system user - you might want to look at Password Policies and maybe set password to Never Expires. Now this is bit dangerous so there would be other things you might want to read up about: "API only user" (can't login to website), maybe even locking down the account so it can login only from certain IP ranges or at certain times when the job's supposed to be scheduled...
Connected App and OAUth2 stuff - it's a good idea to create one, yes. Technically you don't have to, you could use SOAP API to call login, get session id... But it's bit weak, OAuth2 would give you more control over security. If you have sandboxes - there's little-known trick. You can make connected app in production (or even totally unrelated Developer Edition) and use client id & secret from it to login to sandboxes. If you create app in sandbox and you refresh it - keys stop working.
(back to security piece - in connected app you can let any user allow/deny access or sysadmin would allow only say these 3 users to connect, "pre-authorize". Could be handy)
Login - there are few REST API ways to login. Depends on your decision. if you have 1 dedicated user you'll probably go with "web server flow". I've added example https://stackoverflow.com/a/56034159/313628 if you don't have a ready SF connection library in your programming language.
If you'll let users login with their own credentials there will be typical OAuth "dance" of going to the target page (Google login, LinkedIn, Twitter...) and back to your app on success. This even works if client has Single Sign-On enabled. Or you could let people type in their username and pass into your app but that's not a great solution.
Pull the actual report already
Once you have session id. Official way would be to use Reporting API, for example https://developer.salesforce.com/docs/atlas.en-us.api_analytics.meta/api_analytics/sforce_analytics_rest_api_get_reportdata.htm
A quick & dirty and officially not supported thing is to mimic what happens when user clicks the report export in UI. Craft a GET request with right cookie and you're golden. See https://stackoverflow.com/a/57745683/313628. No idea if this will work if you went with dedicated account and "API access only" permission.

Azure AD | Conflict when logged in with another Azure Account

I have a Asp.net MVC application that uses Azure AD and OpenID Connect OWIN middlewares to handle authentication. Everything works fine except for one thing : if a user is already logged-in on another Microsoft Application lets say a Office 365 account or maybe a live mail account, when trying to login it recives a page saying that it is not allowed to log into my app, which is correct, but some how I need to catch that situation in my code to allow the user to sign in with a different account. Is there a way of doing that? This is by design? I mean : the user have to log in only with a live/azure account at the time ? I couldn't find any documentation about this.
As of today there is typically one user at a time, but we will soon support for you a way to select a specific user instead of automatically signing you in with the most recent one.
One way you can work around this today is by injecting the parameter "prompt=login" in your sign in requests. You can do that in the RedirectToIdentityProvider notifications, similarly to what is showin in http://www.cloudidentity.com/blog/2014/11/17/skipping-the-home-realm-discovery-page-in-azure-ad/ for domain_hint. This will cause the sign in experience to always start with a fresh prompt even if the user is already signed in. The draw back is that you'll never get SSO this way. Hopefully our account switiching feature will become available soon, keep an eye on http://blogs.technet.com/b/ad/ for announcements

What is this "Not logged in" screen from "_ah/login" that appears with oauth2client?

I'm playing with the oauth2client.appengine Oauth2Decorator and it interjects it's own screen asking for an email address:
The URL is http://127.0.0.1:8080/_ah/login?continue=http%3A//127.0.0.1%3A8080/mypage
I'm guessing that its intention is to mock being different users during development? But that leaves some questions:
Does it only appear on the dev server?
Do I have to do anything to make it go away when deploying to production, or is that magic?
How do I turn it off for development?
What does it actually do?
if the user is being redirected to an oauth consent page nonetheless what's the point of this?
As you can see I just don't get it. I do see that it gives my get_current_user() a result - a user instance with the email address that I submit.
I recognise that this is effectively the same question as
"How to Bypass Local Login Screen with Oauth2 and GAE", which seems to conclude that the whole oauth2client library is fairly useless and it is best that we all go off and write own authentication flows? Seriously?
If that's the state of things alternative suggestions are welcome (in the comments). My workflow is to send the user off to be granted permissions via Google's Oauth so my webapp can proceed to do stuff on their behalf.
If you want to use the get_current_user() that is provided by Google you can't really avoid it and it is actually something very useful. If you want to do your own authentication stuff then just don't use it and you won't be redirected to /_ah/login.
In short this is just to simulate locally the actual Google Login. It would be a huge mess to login to your actual account while on development mode and it will be really hard to simulate multiple users. That code is not executed online and instead you are being redirected to Google for approval.

SharePoint 2013 Unauthorized exception for provider-hosted Apps

I receive "Unauthorized" exception on the host side for a provider-hosted App for SharePoint 2013.
Uri hostWeb = new Uri(Request.QueryString["SPHostUrl"]);
using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(hostWeb, Request.LogonUserIdentity))
{
clientContext.Load(clientContext.Web, web => web.Title);
clientContext.ExecuteQuery();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Certificates were installed, Anonymos access was disabled. I can't understand the reason of this problem.
I have ran into the exact same problem before... i resolved it by implementing OAuth and have it redirect to the app main page with "write" permission.
Response.Redirect(TokenHelper.GetAuthorizationUrl("mysharepoint.com", "Web.Write", "myapp.com/default.aspx"));
Basically what this does is that it'll authentication the login user with your sharepoint site, once it's authenticated, it'll redirect (with write permission) to your app site.
Here is how to implement OAuth: http://msdn.microsoft.com/en-us/library/office/jj687470(v=office.15).aspx
Looks like this is High Trust App. If you have exhausted the tips at http://msdn.microsoft.com/en-us/library/fp179932.aspx, then there is an illformed SPTrustedSecurityTokenIssuer. You can find out all of them using the below PS. Ideally it should be IssuerId#Realm. If there is one which is not, then remove that. But remember not to remove first one which is for workflows
Get-SPTrustedSecurityTokenIssuer | select Name,RegisteredIssuerName
First you have to Check user in 'Request.LogonUserIdentity'. actually this happens when your user does not have access to your site in IIS.
so to set the correct user in 'Request.LogonUserIdentity' follow the below steps:
open your IIS --> Authentication -->Anonymous Authentication --> edit--> Specific user [ User which you get in 'Request.LogonUserIdentity']. --> iisreset
now user have permission to access your IIS site.

Resources