Determine identity on IdentityServer4 *SERVER* - identityserver4

Please read this carefully, as I'm pretty sure people will answer a different question to the one I'm asking.
I have an IdentityServer4 server, that allows users three methods of authentication (we have multiple sources of truth at the moment): custom (userid/pwd in SQL), ldap (user/pwd in AD) & integrated windows (no password required). These work lovely, and when I'm in my client MVC application I can get at the identity and claims, regardless of which method I used to authenticate.
The question I have is how do I understand which user has logged on to the SERVER (not the client MVC!). I can see the server is maintaining cookies, which must hold this info. Bear in mind that User.Identity.Name will return the Windows Authentication information before they have 'logged in' to my software. i.e. User.Identity.IsAuthenticated always returns true. They may well go on to choose the SQL authentication method.
I'm guessing that is has something to do with HttpContext.Authentication.GetAuthenticationInfoAsync but I'm not clear on what authenticationScheme to pass in, as the last call to SignInAsync called an overload that didn't specify that.

Ok, I understand what is going on here now. The way I check to see if the user is authenticated on the server is to check for the sub claim. That will only be present if they've been through the authentication process.
var sub = User.FindFirst(JwtClaimType.Subject)?.value;
If that's null then I know they're not authenticated. If it's not null then I know I can read the JtwClaimType.Name and it NOT be their Windows Authenticated account name.

Related

Google data studio User_Pass authorization

"Issue description copied..."
I'm building a partner connector, which relies on a user name and password to connect to database (very similar to the existing Postgres / MySQL connectors provided by Google). In order to verify the credentials, I also need the database host information to be present in addition to username and password and this is the base of my problem.
The Google build connectors conveniently are allowed to collect user credentials and the database related information at the same time. Unfortunately, that doesn't seem to be the case for partner connectors as stated in the requirements
Point 5 "Use appropriate authentication method in getAuthType(). Do not request credentials via getConfig()."
The authentication itself happens before any other configuration details are known (there is just a dialog for username and password) and there doesn't seem to be a way to request additional information on the authentication screen itself. Once the credentials have been entered, the verification also happens immediately, before the configuration is being shown in the next step.
Once credentials are validated successfully, Datastudio then assumes the schema and data can be requested.This excludes the option of a dummy confirmation, because there doesn't seem to be a way to tell credentials are invalid and need to be changed after checking the other configuration details on the next screen.
That makes me unsure, how to determine valid credentials in my use case as I need to know the variable endpoint to authenticate against. I definitely want to avoid storing any user credentials myself in an external database, because this opens up another can of worms.
Has anyone successfully solved a similar issue before and can provide guidance here?
This is a known limitation of the authentication methods for Community Connectors.
A workaround would be to use authtype NONE and then request the credentials and database information in the config. This is, however, not a recommended approach.

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.

Adding custom Claims to ADFS from SQL Server

I am trying to add the custom Attributes via the SQL, and I'm following the steps on [https://blogs.technet.microsoft.com/vinitt/2013/04/15/how-to-use-to-custom-sql-attribute-store-to-generate-claims-and-authorize-user]
I got the SQL Server setup, with the table 'attributes', but then I get to the step where it talks about the relaying party trust... Just edit the non-existent relaying party trust. (Application is working correctly right now, it is a website using ADFS to provide the Authentication, but not the authorization) - I had code for the API side to query the database and add Claims on the fly, but that only works for the server side code, we really need those claims in the JWT.
So, looking at this article everything looked great. I got the SQL Server, and I just need to add the rule to hit the server once the person's logon is validated.
Sounds like a piece of cake, but there is no where to add the claim rule - as I don't have (or need?) any relaying party trust - this can be handled 100% by the AD FS Server, so no need for any relaying. I tried to add one, but couldn't get past the first question. Guessed on that one, and couldn't get past the 2nd question. At this point I gave up... I doubt that entering random data into the form is going to work.
Can someone tell me how to add this? Please note: this is NOT a sharepoint site, and has nothing to do with Sharepoint. It is a .Net Site running an angular application that redirects to the ADFS Server and gets redirected back with the token..
So, anything wrong with this claim Rule:
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"]
=> issue(store = "SQL", types = ("http://schemas.microsoft.com/ws/2008/06/identity/claims/role"), query = "SELECT role from dbo.ADFS_attributes where logon={0}", param = c.Value);
Specifically, the attributes table has logon and role, and I'm trying to create roles based on records for that user. (In this case, it should create one per each result (I hope))
I've tried to change this to 'select 'Admin' role' in order to just always return a role to use, but that doesn't work either. I don't see any errors in the event log, just nothing... no change to the JWT that comes back.. (Still the same number of claims) - I can't even seem to add 'email' as a pass through claim, so I'm missing something here, or else, it is missing something here.. I don't know what.
OK, to make SURE this was working, I added the following claim rule:
=> issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Value = "Admin");
Yep, added it right to the Active Directory Provider trust, so it would Always add the 'Admin' role. Nada.
I added it directly to the 'Web Application' / Issuance Transformation Rules, so there is no chance that it wouldn't be added.... Nope, nothing.
I also verified that the 'role' was in the claim description, and checked to publish as both accepted and sent...
Still getting the same old 10 items in the JTW that I always got..
Oh, and I tried restarting the 'Active Directory Federation Services' service...
And marked 'clear browser cache' when the debugger is up on the web page.
Sounds like ADFS just doesn't actually work, or none of the claims rules run. Is there a global setting somewhere that says 'enable custom rules' that needs to be turned on?
This is a better article since it doesn't reference SharePoint.
Also the rules should be "issue" rather than "add".
On the RP side, add the claims rules.
You need a RP trust because this is the application that is going to get the claims rules.
To add a RP trust manually, refer this.
Also, you mention JWT? What protocol are you using? SAML? OpenID Connect?
Turns out that you can add the rules to the 'Application Group' / "Web Application", and select the "Issuance Transform Rules" and add your SQL Claim rule there:
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"]
=> issue(store = "SQL", types = ("http://schemas.microsoft.com/ws/2008/06/identity/claims/role"), query = "SELECT role from dbo.ADFS_attributes where logon={0}", param = c.Value);
This allows you to add multiple roles if you have multiple roles.
The primary reason I wasn't seeing this was that the UI that was put on this was (somehow) posting a different token (without my roles) back to the API Server. I'm looking into where it got that token, why the token wasn't validated, (didn't come from the server, or it would have had my roles added)... Very strange,
Solved the issue by using PostMan to post to the server and then looked at the returned JWT that was good...
It seems that all JWT signing verification wasn't done by the last person...

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

Can native applications make use of OS SSO login information?

If a user logs in to their computer using a Single Sign-On system such as Active Directory, LDAP, or Kerberos, is it possible for applications they run to know who they are and what system they authenticated with? Can I get enough information out of these systems to verify their identity without requiring any additional user input?
Specifically, I would like to be able to check these things:
Did they log in via a single sign-on system at all, or are they just using a regular user account on this machine?
What system did they use?
Does the system have some URI that would distinguish it from any other directory?
What is the current user's distinguished name in that directory?
Can I get some information which I can pass to another host to prove to that host that the user is who they said they are? For example, a token that can be used to query the SSO system.
I'd assume all of these things should be possible, and in fact encouraged, but I am not positive. I'm sure the method of getting at this information is
SSO (at least with Kerberos which is used by ActiveDirectoy) is based on a token. As soon as the user requests access to a kerberized system the system queries for the token and checks its validity for accessing the system. It's as good as querying for username and password. when the user did not log in with an Kerberos-account there is no tiket so no automated access.
using the token you can get the users login- name and from that you can then use that to query the SSO-backend (typically LDAP) for more information on that user.
LDAP is not an SSO-system as it is simply a storage query protocol but it is often used as backend for SSO-systems.
The problem often is kerberizing an application. for Webapps that means you have to kerberize the webserver so that that one then can handle the authentication process with the SSO-service and then pass that information on to the unferlying webapp.
Hope that answers you questions.
for more information have a look around the web for kerberos
You are really asking about two things:
Authentication: Who are you?
Authorization: What are you allowed to do?
Kerberos really only answers the first question, you need a secondary system like LDAP or Active Directory ( which is both kerberos and ldap in a single server) to answer the second.
If your system is using kerberos correctly, any user login should have an associated kerberos ticket. With this ticket, you can request "service" tickets
to prove your identity to remote servers that support kerberos. The ticket
contains your principal identity in the realm ( user#DOMAIN.NET ) that can be
used to query authorization systems.
However, the details required to get all the moving parts in that sentence working together "on the same page" so to speak can be very complex. The remote service has to support accepting kerberos credentials, it has to be either in the same realm or have a cross realm trust relationship configured.... The list
gets pretty long. Depending on your exact application environment, using all these things can be fairly trivial, or it can be next to impossible.

Resources