First of all, a kind user named "leppie" tried to help me but I couldn't get the answer I am looking for and it's kind of an urgent matter.
I run a windows service in Windows 7 with LocalSystem account (Since this win service will be installed many computers remotely and silently, I guess I need to use LocalSystem in ServiceInstaller.Designer.cs by the code below:
this.ProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.ProcessInstaller.Password = null;
this.ProcessInstaller.Username = null;
When I run this windows service the code below cannot get the currently logged in user's credentials (the users do not have admin privileges, not even myself).
using (DirectoryEntry de = new DirectoryEntry("LDAP://MyDomainName"))
{
using (DirectorySearcher adSearch = new DirectorySearcher(de))
{
adSearch.Filter = "(sAMAccountName=" + Environment.UserName + ")";
SearchResult adSearchResult = adSearch.FindOne();
UserInternalEmail = GetProperty(adSearchResult, "mail");
}
}
I have been suggested to run the WinService under a AD/LDAP/domain account, but which user could this be?
this.ProcessInstaller.Account = System.ServiceProcess.ServiceAccount.<User ? LocalService ? NetworkService>;
this.ProcessInstaller.Password = "adminpassword";
this.ProcessInstaller.Username = "adminusername";
I mean, lets say an ABC user is an admin and lets say I knew the password and username of this ABC admin, but when this admin changes the password, I think this will effect my winservice which will be running on 70 computers.
Is there a way to retrieve the user credentials on active directory? I would be really appreciated if you provide me some code samples..
Thank you very very much,
The problem is that Environment.UserName will always return the username of the service account under which the service is running, not the user logged into the machine.
See this question for information on how to get the names of users logged into the workstation. Keep in mind that Windows will allow multiple users to be logged in at the same time.
Related
Is there a way to uniquely identify a user that has logged on my application based on his device/machine ?
In a lot of cases, the IP is enough, but in case when the client has multiple machines behind a NAT, then the same IP is exposed, so I can't tell them apart. it should have same id irrespective of browser.
for e.g. If the user logs in on his account with computer A, then log in on the same account with computer B that share the same router, I need to get id apart those two devices.
I don't know if this is possible, but it would be life saving if it is.
I was faced with this problem where I wanted to ask for Google Authenticator on sign in but only once for each device used by a user. I used a function to give me a device id based on the hostname, the MAC address, and the IP address. I know the MAC address isn't always reliable so I thought combining the data into one string might be a way round it. Our application is limited to <100 users and most of them access from the office or home so I feel it should be good enough.
I put the IP address function (which gets the IPV4) into a separate function as I check whether they are in office (on 192.168..) or external before checking the device ID. The list of device ID's associated with a user is stored in a SQL table and checked after username/password entry but before log in is completed to decide whether to request a 2FA code.
Here's the code:
dim thisDeviceId as String=GetClientDeviceId()
public Function GetClientDeviceId() As string
Dim mac As String = String.Empty
For Each netInterface In NetworkInterface.GetAllNetworkInterfaces()
If _
netInterface.NetworkInterfaceType = NetworkInterfaceType.Wireless80211 OrElse
netInterface.NetworkInterfaceType = NetworkInterfaceType.Ethernet Then
Dim address = netInterface.GetPhysicalAddress()
mac = BitConverter.ToString(address.GetAddressBytes())
End If
Next
return string.Format("{0}-{1}-{2}",dns.GetHostEntry(HttpContext.current.Request.ServerVariables("REMOTE_ADDR")).HostName, mac,GetClientDeviceIpAddress())
End Function
public Function GetClientDeviceIpAddress() As string
Dim ipv4Address As String = String.Empty
For Each currentIpAddress As IPAddress In Dns.GetHostAddresses(Dns.GetHostName())
If currentIpAddress.AddressFamily.ToString() = System.Net.Sockets.AddressFamily.InterNetwork.ToString() Then
ipv4Address = currentIpAddress.ToString()
Exit For
End If
Next
return ipv4Address
End Function
Even though it's not bulletproof and could be improved upon it might help someone.
We installed ranger user-sync and able to sync all external users via open LDAP. This user sync is only happening when we restart ranger user sync. I would like to see if user can sync in real-time. Please help me how can I achieve this.
Below properties configured in install.properties. Rest other properties, I kept default.
SYNC_SOURCE = ldap
MIN_UNIX_USER_ID_TO_SYNC = 500
MIN_UNIX_GROUP_ID_TO_SYNC = 500
SYNC_INTERVAL = 1
SYNC_LDAP_URL = ldap://<Open LDAP server IP and port>
SYNC_LDAP_BIND_DN = cn=admin,dc=example,dc=org
SYNC_LDAP_BIND_PASSWORD = <password>
SYNC_LDAP_SEARCH_BASE = dc=example,dc=org
SYNC_LDAP_USER_SEARCH_BASE = dc=example,dc=org
SYNC_LDAP_USER_SEARCH_SCOPE = sub
SYNC_LDAP_USER_OBJECT_CLASS = person
SYNC_LDAP_USER_NAME_ATTRIBUTE = uid
SYNC_LDAP_USERNAME_CASE_CONVERSION=none
SYNC_LDAP_GROUPNAME_CASE_CONVERSION=none
SYNC_LDAP_REFERRAL =follow
#Shailendra. You may need to schedule the restart of ranger or the user sync directly via chron. I was able to find some info about the usersync sleep time.
Check for and reduce the value of this property in your configuration for the usersync sleep time:
ranger.usersync.sleeptimeinmillisbetweensynccycle (reference)
This article may help too as it suggest a java code to run usersync manually:
https://community.cloudera.com/t5/Support-Questions/Is-there-a-way-to-force-Ranger-user-sync-to-run-manually/td-p/110370
So before showing my code, let me explain what steps I took to 'properly' set up service account environment.
In google developer console, created service account. (this produced Client ID (which is a long number), Service account (xxxxx#xxxx.iam.gserviceaccount.com), and private key which I downloaded in P12.
In Admin console, put the client ID with appropriate scope. In my case the scopes I added is https://www.googleapis.com/auth/admin.directory.group.readonly and https://www.googleapis.com/auth/admin.directory.group.member.readonly.
In my code, correctly set up private key path and other environments.
def getDirectoryService: Directory = {
val httpTransport: HttpTransport = new NetHttpTransport()
val jsonFactory: JacksonFactory = new JacksonFactory()
val credential: GoogleCredential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("xxxxx#xxxx.iam.gserviceaccount.com")
.setServiceAccountScopes(util.Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY, DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY))
.setServiceAccountUser("admin#domain.com")
.setServiceAccountPrivateKeyFromP12File(
new java.io.File("/pathToKey/privatekey.p12"))
.build()
val service: Directory = new Directory.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential).build()
service
}
And then I attempt to execute something like this:
service.groups().list().execute()
or
service.groups().list("domain.com").execute()
This code would result in,
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant"
}
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.company.project.GoogleServiceProvider.getGroups(GoogleServiceProvider.scala:81)
at com.company.project.ProjectHandler.handle(ProjectHandler.scala:110)
at com.company.common.web.DispatcherServlet.service(DispatcherServlet.scala:40)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:224)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1174)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1106)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:524)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.lang.Thread.run(Thread.java:745)
What could have I done wrong? I have been searching solution for past two days, and tried many things. One of the solutions I am not still not sure of is ntp syncing (as in how to exactly sync server time to ntp).
Any adivce would be very helpful, thank you!
UPDATE: I also made sure to activate the Admin Directory SDK, and enabled the Domain-Wide Delegation on developer's console.
UPDATE #2: I forgot to mention that, the admin account is not the owner of the project itself. So basically, I am a member of a domain, and I created a project, so I am the only owner of the project and the service account.(I am not the admin). But should an admin be owner of the project and create service account in order for this to work properly???
Ok, my problem was that in setServiceAccountUser I put admin group email address, not the actual user account. Apparently, it doesn't allow putting in group email (alias) address into setServiceAccountUser.
So after putting in an actual user account with admin privilege, it seems to be working.
I still wonder what would be the best practice though. As in, should I create a separate user account with admin privilege just for the project? I definitely don't want to just put in an admin account email address in my code.
I am using Google OAuth for Google signin with Odoo.
Everything works fine and I can sign in using google with no problem. However, I cannot open multiple sessions using my same google credentials.
For example, if I open two sessions, one in chrome and another in firefox, then the older session gets logged out.
I don't understand what's the problem because no matter how many sessions I start if I log in using my username and password separately, without using google OAuth, none of the sessions get logged out - works fine.
I was wondering it has got something to do with the code, so I did a lot of tweaks but nothing works. I saw that at one point it cannot get the session information of older sessions. However my question is not about the code.
My question is, is there any configuration or setting to be set in google OAuth or Odoo 8 which lets users have multiple sessions at the same time or is there any setting while using google OAuth with Odoo that I need to know for this?
Any idea would be really helpful as I've been struggling for days with this. Thanks!
I have build a module for Odoo V9. Without this module, Odoo save only one token. But when you use odoo in multi computer, you use one token for each computer.
By default odoo don't support multi token. You need to modify the code of module auth_oauth.
With this module it save all token, like that you can have multi connection.
You can donwload and instal this module : https://github.com/IguanaYachts/auth_oauth_multi_token.git
class ResUsers(models.Model):
_inherit = 'res.users'
oauth_access_token_ids = fields.One2many('auth.oauth.multi.token', 'user_id', 'Tokens', copy=False)
oauth_access_max_token = fields.Integer('Number of simultaneous connections', default=5, required=True)
#api.model
def _auth_oauth_signin(self, provider, validation, params):
res = super(ResUsers, self)._auth_oauth_signin(provider, validation, params)
oauth_uid = validation['user_id']
user_ids = self.search([('oauth_uid', '=', oauth_uid), ('oauth_provider_id', '=', provider)]).ids
if not user_ids:
raise openerp.exceptions.AccessDenied()
assert len(user_ids) == 1
self.oauth_access_token_ids.create({'user_id': user_ids[0],
'oauth_access_token': params['access_token'],
'active_token': True,
})
return res
#api.multi
def clear_token(self):
for users in self:
for token in users.oauth_access_token_ids:
token.write({
'oauth_access_token': "****************************",
'active_token': False})
#api.model
def check_credentials(self, password):
try:
return super(ResUsers, self).check_credentials(password)
except openerp.exceptions.AccessDenied:
res = self.env['auth.oauth.multi.token'].sudo().search([
('user_id', '=', self.env.uid),
('oauth_access_token', '=', password),
('active_token', '=', True),
])
if not res:
raise
If you follow the steps above you will be able to successfully configure Google Apps (Gmail) with OpenERP via the OAuth module. The only thing i was missing is an extra step I found in a youtube video; you have to:
Go to Settings - Users
To the users you want to give OAuth access, send them a password reset by using the "Send reset password instructions by email" option.
Ask your users (or yourself) to use the link they receive in their email, but, when they open it, they will only see the log in screen with the "Log in with Google" option. (no typical change password option available)
Use the proper Google account and voila! - Now it connects smoothly.
The Youtube video that show how to log in with Google in OpenERP: http://www.youtube.com/watch?v=A-iwzxEeJmc
and if configuration of Oauth2 and odoo see this link for more detail
https://odootricks.wordpress.com/2014/09/18/setting-up-google-apps-authentication-for-odoo/
Use Case : A single user with “single user name” should be able to use data available in different tenant without relogin.
Expected Flow :
User “A” login into tenant 1
He done some activity and able to access all tenant 1 data
He clicks on the “switch tenant” link and after that he should be able to access all data related to Tenant 2
Environment :
Grails v2.1
spring-security-core v1.2.7.3
multi-tenant-single-db v0.8.3
I am using following auto generated class
SpringSecurityTenantRepository
SpringSecurityTenantResolver
I used following code in controller but it did not work.
def switchedTenentId = params.switchedTenentId
if(switchedTenentId != null && !"".equals(switchedTenentId))
{
def currUser = springSecurityService.currentUser
springSecurityService.currentUser.userTenantId = new Long(switchedTenentId)
}
I googled but did not find any solution. I like to know the logic, solution or any sample code.
Thanks
Here is what I did:
User u = User.get(springSecurityService.currentUser.id)
u.userTenantId = params.switchedTenentId.toInteger()
u.save flush: true
springSecurityService.reauthenticate u.username
It worked like a charm.