SSO equivalents to Windows AccessCheck call - winapi

We have an windows app that runs as an Administrative account but we need to determine the access rights to files and directories of a particular user that is logged in to the app.
One solution we have used is to use the user name only to generate an access mask:
BuildTrusteeWithName(&trustee, username);
GetEffectiveRightsFromAcl(pSecurityInfo->pAcl, &trustee, pAccessMask);
The problem with this is that it takes quite a long time on some customer sites with complex DFS setups. We believe the time is taken in looking up the user's groups etc...
So another solution we have used is to cache the user name and password to 'impersonate' the user, temporarily caching a handle to the 'impersonation' token:
// Here we get the handle to the 'impersonation' token
LogonUser(owner, NULL, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, pTempHandle);
DuplicateToken( *pTempHandle, DEFAULT_IMPERSONATION_LEVEL, pOwnerHandleCacheEntry->pHandle );
// This is then called for all files and directories traversed. pOwnerHandle is the handle of the 'impersonation' token obtained above.
// This means the overhead of getting the user's groups etc... is only done once.
AccessCheck(pSd, *pOwnerHandle, MAXIMUM_ALLOWED, &genericMapping, &privilegeSet, &dwPrivSetSize, &fileAccessMask, &accessStatus);
The problem with this is if we wish to introduce Single Sign On, we don't have access to the user's password. This will leave some sites that wish to use SSO with a system that doesn't perform very well as they will need to switch back to first solution (above).
So, my questions are:
1) Is there a way of caching the user information used to build the access rights using just the user name (in order to avoid doing lookups every time) ?
2) Failing question 1 (above), is there an equivalent of our preferred solution within an SSO environment (for example: impersonating a user using a kerberos ticket)?

Roughly speaking, the SSO equivalent of LogonUser is SSPI. SSPI allows a server to authenticate a client without needing the client's password. After successfully authenticating the client, the server will have access to a user token, but as with everything in SSPI it's complicated how to get it. From there, you can call AccessCheck which should be very fast.

Related

Allow admin user to login as other users

Is there any way to login other users account for admin user ?
Currently authentication based on Meteor Accounts
I saw this post but didn't working at all now.
The feature is important for us because when user have problem in system then admin need to see it this by simulating user account.
Thanks in advance.
It seems you want to impersonate a user. This means that you want to have Meteor.userId (or this.userId depending on context) reflect the _id of a specific user both on the client and the server.
afaict the only way to do this is to login as the user. Presumably you don't want to ask the user for their password so you have a couple of choices:
Save their existing password, replace it (temporarily) with a password of your choosing, then after you're done impersonating their account, restore their existing password.
You probably don't want to ask the user for their password and you don't need to. All you need to do is set aside Meteor.user.findOne(userId).services.password.bcrypt, then reset the password to your temporary value, then restore the original bcrypt value later.
The downside is that the original user would not be able to login while you are logged-in. Plus it's really hacky.
Extend Meteor's Accounts package to provide impersonation capability in a more elegant manner.
You might also look at validateLoginAttempt. The docs are unclear as to whether a failed login attempt could be overridden with a successful one but if it could then that would provide another pathway to solve your problem.
Instead of logging in as the users, which requires their password and which is a total no-no, you may use rather alanning:roles and allow the admin to assign the role of any user in order to draw views based the user's role.
This requires a well designed role system.
As a plus you could then at least load the documents associated with the user who you want to support.
This requires a well designed document and data model.
But generally spoken you should rather focus on writing good tests (test driven development) for components as unit tests, integration tests and UI tests.
This will reduce the need to manually view the app as an end user a lot.
The most common end user problems can be reduced by creating a good knowledge base like a wiki or video tutorials.
Even if then an error occurs in the end user side, I would rather try to implement a well designed error log that allows users automatically create tickets on error which also include the error stack.
All the above methods are to be favored before logging in AS THE USER.
As #Jankpunkt has already mentioned alanning-roles I can add something you can use without installing any external package.
Just keep a type key in the profile object of the users collection. Then define some types like 1 for super-admin, 2 for admin, 3 for general etc. Then check the authorisation of particular action by checking the value of user.profile.type key.
Caveats: Make sure you are checking the type in server side. By default profile field is writable from the client end, so if you are putting type field in the profile object make sure that you are not allowing users to modify users collection in the client end.
Here is how to restrict client end update in users collection:
Meteor.users.deny({
update() { return true; }
});
Read more on roles and permissions here:
https://guide.meteor.com/accounts.html#roles-and-permissions

Confusing how Laravel passport API security works

Client sends username and password to the server.
Server then checks if this user is authenticated.
If yes, the server returns an access token for the client...
Then user can use this access token to access protected resources...
The advantage here, is that we are not sending user info via API calls, and the access token will not last for long time, so hackers won't be able to find out user authentication info (user name and password), and if he finds out, the access token won't last long enough to do anything with it.
That's how I understand Laravel passport API security.
The confusing thing here, is that on first API call, user has to send user name and password, so hacker still have big chance to find out user info!!!
I know that there is something wrong with my understanding, and that's why I get confused, any explanation would be very appreciated.
There must be a way to prove your identity to authorization server, and one way is to provide username and password. The way you're gonna achieve communication between authorization server and your client application is totally up to you as long as it uses HTTP. As stated in RFC-6749:
This specification is designed for use with HTTP ([RFC2616]). The
use of OAuth over any protocol other than HTTP is out of scope.
Of course it's always advised to use HTTPS whenever possible. Just because HTTP is mentioned in document, doesn't mean HTTPS cannot be used because HTTPS is just encrypted version of HTTP.
Other thing I wanted to mention is that you don't need to provide username and password, there are several grant types where you can, for example, instead of username and password you can provide client_id and client_secret which is used in Client Credentials grant type.
If you are new to this I believe this all is little bit confusing for you. To summarize the purpose of OAuth2 to you (as far as I get it), is:
To separate role of the client (which can be browser, mobile etc.) from the resource owner (usually the owner of account). Why? Because if there is no separation, the client has access to user's sensitive data.
Imagine that the first point is secure enough for communication. But what happens if someone gets their hands on the session you have? They have access to all! This is why OAuth introduces scopes, where depending on the scope user has with provided access token has limited access to resources. Scope can be read, write, share etc. - this implementation is up to developer. So if someone gets their hands on your access token, because of scope they only have a limited access to resource.
These are one of my reasons, while RFC-6749 has better explanation:
Third-party applications are required to store the resource
owner's credentials for future use, typically a password in
clear-text.
Servers are required to support password authentication, despite
the security weaknesses inherent in passwords.
Third-party applications gain overly broad access to the resource
owner's protected resources, leaving resource owners without any
ability to restrict duration or access to a limited subset of
resources.
Resource owners cannot revoke access to an individual third party
without revoking access to all third parties, and must do so by
changing the third party's password.
Compromise of any third-party application results in compromise of
the end-user's password and all of the data protected by that
password.
To learn more about OAuth2, it's grant types and purposes, I recommend you to read this:
An Introduction to OAuth 2
Mentioned RFC-6749, even though it can be difficult to read because of technical writing.
Hope I clarified at least a small piece of blur.

Creating a service for user (S4U) token

The Windows Task Scheduler can create tasks that run with the account of a particular user, without storing the user password. They call it "S4U", service for user. This should work something like the scheduler creates such a token for the current user and can use it to run the scheduled process under that user account. They claim that it cannot access network or encrypted resources with this system. The scheduler itself runs with the SYSTEM account for it to work. Here's an article that describes it. The relevant quote from it:
TASK_LOGON_S4U is yet another option that provides a more secure
alternative. It takes advantage of a service for user (S4U) logon to
run the task on behalf of the specified user, but without having to
store the password. Since the Task Scheduler runs within the local
system account, it can create a S4U logon session and receive a token
that can not only be used for identification, but also for
impersonation on the local computer. Normally a S4U token is only good
for identification.
I need to use this authentication scheme in my application, but can't let the Task Scheduler do it but need to do it myself, because I need it for any number of accounts. Whenever a user registers a task with my application, any followup tasks must run under the same user. But since they cannot overlap, I need to do the serialisation myself.
I cannot find any information about this "S4U" thing. How could I implement it in my application? C# preferred, but WINAPI and C is okay.
Update: This is what I've tried, and it doesn't work.
// The WindowsIdentity(string) constructor uses the new
// Kerberos S4U extension to get a logon for the user
// without a password.
WindowsIdentity wi = new WindowsIdentity(identity);
WindowsImpersonationContext wic = null;
try
{
wic = wi.Impersonate();
// Code to access network resources goes here.
}
catch()
{
// Ensure that an exception is not propagated higher in the call stack.
}
finally
{
// Make sure to remove the impersonation token
if( wic != null)
wic.Undo();
}
But I've got the impression now, that you can't just say you want to be a certain user. Not even as System. You need to be logged in as that user and can generate some token that allows you to become that user later again, without the password. So this must be a two-step thing, first I need to get the token and store it on disk; later I can use that token to impersonate. None of the examples explains this.
"The computer may not be joined to the domain"
S4U requires access to a KDC. S4U is actually two protocols. S4U2Self and S4U2Proxy. What it is doing is using an addition to Kerberos to get service tickets for a user, but that account that goes and gets the ticket has to have a special delegation enabled on it. See here for this set up.
But unless you are actually letting the process die etc, why not just get the users service ticket or TGT? Is your application local or is it a service running remote to the user?
Task scheduler needs to go get a new one because a service ticket isn't valid forever. Or in some delegation schemes the user hasn't passed a service ticket to the Application Server and then the AS goes and requests and service ticket via S4U2Self, and then uses that service ticket to request a ticket to a second service via S4U2Proxy.

What permissions are required for the Win32 LogonUser function?

Suppose that I want to run the LogonUser function in my code for a user with uid Bob, what permissions must Bob have for me to be able to call this function to log in as Bob successfully?
I don't know if there is a list anywhere since parts of the security system can use custom "plugins" (Authentication Packages, Security Support Provider Interface/Security packages and GINA/Credential Providers) and they might have other requirements.
On a default system it probably goes something like this:
The named user account passed to LogonUser needs the SE_*_LOGON_NAME account right that matches the logon type (LOGON32_LOGON_*) and the logon needs to pass the LSA and/or domain controller requirements (Logon hours, password not expired etc)
The process calling LogonUser needs SE_CHANGE_NOTIFY_NAME (Everyone has this by default), maybe SE_TCB_NAME (Required on Win2000). If you are going to call CreateProcessAsUser on the returned token you also need SE_INCREASE_QUOTA_NAME and maybe SE_ASSIGNPRIMARYTOKEN_NAME...
If you just want to start a process as another user you might want to use CreateProcessWithLogonW, if you just want to validate the credentials this KB article has a code example that does not use LogonUser (It seems like it might have some guest account issues though)

How can I avoid using server-side sessions for authentication in a Java webapp?

I'd like to secure access to resources in my web application, so I authenticate my users using the standard mechanisms and use server-side sessions to preserve the authenticated state.
I'd like to deploy across multiple systems in a load balanced configuration, but I don't want to start synchronising session state across my infrastructure. Are there ways (using either spec-driven facilities in Java EE or commonly available libs like Spring Security) of preserving the authentication state of a user without server-side sessions, for example by pushing the required state back out to the client? If so, are there additional risks I need to be aware of?
Update - I am using declarative security as per Java EE webapp specs and authenticating via an LDAP repository.
I'm not aware of a framework solution, but the following does work:
After the user successfully logged in you create a secured token and set it's value as a cookie. The token contains all information required (user ID, creation time, etc.) and is encrypted using some algorithm. So all nodes in your cluster can read the token, decrypt it and identify the user. Then you create a ServletFilter intercepting all requests, examining the token and set corresponding user credentials for e.g. ServletRequest.getRemoteUser() by using an HttpServletRequestWrapper.
One way to solve the problem. But you must take care, self-made security must be well-thought-out.
You can store some kind of token in a cookie after authentication, and manage session attributes yourself. E.g., have a database table whose primary key is the authentication token and stores user session data... Don't forget to implement a job to clean inactive "sessions".
As for what you should be aware of, keep in mind that cookies are something easy to access, steal, delete, disable, etc. The authentication token should be something strong and verifiable (hash a combination of the user ip + browser + rotating salt + some other things you can check for).
It is also wise to divide user authentications in two levels. "Has the cookie" and "just validated the cookie"... Let's say that "has the cookie" is a state that can be there for half an hour (or maybe more) which allows the user to navigate the site. "Just validated" state is for important operations, and should require the user to enter it's credentials again. The timeout for this "just validated state" shouldn't be much longer than a couple of minutes.
Keep in mind that I'm assuming that your site is not holding really sensitive data. For those situations I would recommend something such as two-way SSL authentication with external tokens or security cards plus rotating token devices plus biometrics authentication :D:D:D... I guess you see my point.
Cheers,
You can use an open id server to authentication thus separating your authentication and application logic.

Resources