Getting credentials of specified user - c#

I wrtitting a windows service. This service has to connect SharePoint service and get data different for each user. sharePoint service return data based on user credentials whitch are set before calling service.
How can I get user credentials by user name and user domain if the service can be run under any account that needs to get this credentials?

Depending on how you add the sharepoint service (web reference or service reference) there are different methods to send credentials with the request.
With a web reference you would add a NetworkCredentials object along the lines of:
SomerService ws = ... //instantiate your service
ws.PreAuthenticate = true;
ws.Credentials = new System.Net.NetworkCredentials("username","pw","domain");
if it´s a service reference with wsHttpBinding then something like this:
Service client = ... //instantiate your service
client.ClientCredentials.UserName.UserName = "domain\\username";
client.ClientCredentials.UserName.Password = "password";
Then you need to store the username/password for each user you are retrieving content for.
If this is a pass-thru service where the client accesses your service and it access sharepoint on the users behalf you have to set up Kerberos authentication and allow impersonation to pass thru. Maybe you could expand on what you are trying to accomplish.

Related

Access TFS work Items using azure worker role

I have a worker role in azure which uses a service account 'myservice' and password is stored in keyvault. Now I have access TFS work Items using TFS APIs.
For testing, I have passed my credentials as
NetworkCredential networkCred = new NetworkCredential("myusername","mypassword");
ICredentials cred = (ICredentials)networkCred;
TfsConfigurationServer configurationServer = new TfsConfigurationServer(tfsUri, cred);
But now I have to pass the service account name 'myservice' and its password.
How do I use service account to access the TFS work Items?
You should be able to consume TFS API using OData Services as explained below:
https://blogs.msdn.microsoft.com/briankel/2011/10/26/odata-service-for-team-foundation-server-2010-v1/
Have a read of this link, then follow the instructions from "Team Foundation Service authentication:" to set up your account/profile to access the Api.
You can then access the resources via the web Api.

Sharepoint Impersonate external web service call

I created a web service running on different machine/IIS than my SharePoint (2013) application node (the double hop issue kicks in). I expose this web service to other services in our company.
Below code snippet will successfully retrieve a SharePoint list using dedicated credentials (i.e. "sp_admin_user").
In my web service I can retrieve the username (w/o password ofc) of a user calling it which also exists in SharePoint by rule.
My question: How do I need to change below code to facilitate impersonation with above username?
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string get_sp_list()
{
SPLists.Lists myservice = new SPLists.Lists();
myservice.Credentials = new System.Net.NetworkCredential( "sp_admin_user", "password123", "domain" );
myservice.Url = "https://sharepoint.company.com/sites/testground/_vti_bin/Lists.asmx";
[.. setting of variables ..]
System.Xml.XmlNode n = myservice.GetListItems(
sidList,
sidView,
query,
viewFields,
rowLimit,
queryOptions,
null
);
[.. compose json ..]
return json;
}
The only user you can impersonate without password is SharePoint IIS Application Pool user (its often NETWORK SERVICE). To impersonate user which is accessing SharePoint pages the computer where SharePoint is running need to have delegation rights to the external service. You can read about it here. This is all about security restrictions.
I advise you to reject impersonation approach, its much more easier to deal with passwords, make anonymous web service call or invent something else.
You can impersonate user like this:
using (var ctx = WindowsIdentity.Impersonate(IntPtr.Zero))
{
//external web service call as "COMPUTER_NAME\NETWORK_SERVICE" user
}
You can also get real user token (not IntPtr.Zero) if you have password.

HttpClient & Windows Auth: Pass logged in User of Consumer to Service

I am struggling to understand and set up a Service and Consumer where the Service will run as the user logged into the Consumer.
My consumer is an MVC application. My Service is a Web Api application. Both run on separate servers within the same domain. Both are set to use Windows Auth.
My consumer code is:
private T GenericGet<T>(string p)
{
T result = default(T);
HttpClientHandler handler = new HttpClientHandler() { PreAuthenticate = true, UseDefaultCredentials = true };
using (HttpClient client = new HttpClient(handler))
{
client.BaseAddress = new Uri(serviceEndPoint);
HttpResponseMessage response = client.GetAsync(p).Result;
if (response.IsSuccessStatusCode)
result = response.Content.ReadAsAsync<T>().Result;
}
return result;
}
In my Service I call User.Identity.Name to get the caller ID but this always comes back as the consumer App Pool ID, not the logged in user. The consumer App Pool is running as a Network Service, the server itself is trusted for delegation. So how do I get the logged in User? Service code:
// GET: /Modules/5/Permissions/
[Authorize]
public ModulePermissionsDTO Get(int ModuleID)
{
Module module= moduleRepository.Find(ModuleID);
if (module== null)
throw new HttpResponseException(HttpStatusCode.NotFound);
// This just shows as the App Pool the MVC consumer is running as (Network Service).
IPrincipal loggedInUser = User;
// Do I need to do something with this instead?
string authHeader = HttpContext.Current.Request.Headers["Authorization"];
ModulePermissionsDTO dto = new ModulePermissionsDTO();
// Construct object here based on User...
return dto;
}
According to this question, Kerberos is required to make this set up work because the HttpClient runs in a separate thread. However this confuses me because I thought the request sends an Authorization header and so the service should be able to use this and retrieve the user token. Anyway, I have done some testing with Kerberos to check that this correctly works on my domain using the demo in "Situation 5" here and this works but my two applications still wont correctly pass the logged in user across.
So what do I need to do to make this work? Is Kerberos needed or do I need to do something in my Service to unpack the Authorisation header and create a principal object from the token? All advice appreciated.
The key is to let your MVC application (consumer) impersonate the calling user and then issue the HTTP requests synchronously (i.e. without spawning a new thread). You should not have to concern yourself with low-level implementation details, such as NTLM vs Kerberos.
Consumer
Configure your MVC application like so:
Start IIS Manager
Select your MVC web application
Double click on 'Authentication'
Enable 'ASP.NET Impersonation'
Enable 'Windows Authentication'
Disable other forms of authentication (unless perhaps Digest if you need it)
Open the Web.config file in the root of your MVC application and ensure that <authentication mode="Windows" />
To issue the HTTP request, I recommend you use the excellent RestSharp library. Example:
var client = new RestClient("<your base url here>");
client.Authenticator = new NtlmAuthenticator();
var request = new RestRequest("Modules/5/Permissions", Method.GET);
var response = client.Execute<ModulePermissionsDTO>(request);
Service
Configure your Web API service like so:
Start IIS Manager
Select your Web API service
Double click on 'Authentication'
Disable 'ASP.NET Impersonation'.
Enable 'Windows Authentication'
If only a subset of your Web API methods requires users to be authenticated, leave 'Anonymous Authentication' enabled.
Open the Web.config file in the root of your Web API service and ensure that <authentication mode="Windows" />
I can see that you've already decorated your method with a [Authorize] attribute which should trigger an authentication challenge (HTTP 401) when the method is accessed. Now you should be able to access the identity of your end user through the User.Identity property of your ApiController class.
The key issue with double hop is delegation of user credential to second call. I want to elaborate a little bit about it. C1 = client browser , S1 = First Server , S2 = Second Server.
Suppose our complete system support window authentication. When user access S1 from browser , its default window credential pass to server S1, but when S1 make a call to S2 , by default it don't pass credential to S2.
Resolution :
We must enable window authentication/ impersonation on both machines.
WE need to enable delegation between server so that S1 can trust to S2 and will pass credential to S2.
You can find some useful details at below links :
http://blogs.msdn.com/b/farukcelik/archive/2008/01/02/how-to-set-up-a-kerberos-authentication-scenario-with-sql-server-linked-servers.aspx
https://sqlbadboy.wordpress.com/2013/10/11/the-kerberos-double-hop-problem/
If you are trying to access service which is hosted on windows authentication then do following.
var request = new RestRequest(Method.POST);
If you want to use applications default credentials which must have access on hosted service server
request.UseDefaultCredentials = true;
or user below to pass the credentials manually
request.Credentials = new NetworkCredential("Username", "Password", "Domain");

Unable to connect to my Tfs server from c# code

We're trying to authenticate to our hosted TFS service account in c# using TeamFoundationServer .net control, here is my code :
NetworkCredential tfsCredential = new NetworkCredential(username, password);
TeamFoundationServer tfsServer = new TeamFoundationServer(tfsAddress, tfsCredential);
tfsServer.Authenticate();
Note that this is not an on-premises TFS server, it is the hosted TFS service at tfspreview.com and we try to sign-in with windows live account and with alternate authentication credentials but every time we try to authenticate, internet explorer open in a new windows and ask for credentials.
If we use the IE prompt to connect it works but we want to store the credentials and connect to the server without asking for the credentials every time,
You can either configure basic authentication under your profile or you can use a service credential. It all depends on what sort of permission you need. The basic auth operates under a user account which tends to be bad practice while the service account had elevated permissions.
Configure basic authentication for TF Service
For basic user authentication you should connect to TF Service and open your profile as indicated. There is a "Credentials" tab on your profile which will let you configure those credentials. This is good for per/user access through the API but is not good if you want to run things through a server or service.
Retrieve TFS Service Credentials
I created an application called the TFS Service Credential Viewer that allows you to retrieve the service credentials for your TF Service instance. This is the same thing that the Build & Test servers do when you configure them locally to work against the cloud.
I hope this helps...
You can try with this code based on impersonation of server
var serverUrl = "";
ICredentials credentials = new NetworkCredential(username, password, domain);
ICredentialsProvider TFSProxyCredentials = new NetworkCredentialsProvider(credentials);
TfsTeamProjectCollection currentCollection = new TfsTeamProjectCollection(new Uri(serverUrl), credentials);
// Get the TFS Identity Management Service
IIdentityManagementService identityManagementService = currentCollection.GetService<IIdentityManagementService>();
// Look up the user that we want to impersonate
TeamFoundationIdentity identity = identityManagementService.ReadIdentity(IdentitySearchFactor.AccountName, username, MembershipQuery.None, ReadIdentityOptions.None);
// Open collection impersonated
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri(serverUrl), credentials, TFSProxyCredentials, identity.Descriptor);
//For example we can access to service WorkItemStore
var workItemStore = tfs.GetService<WorkItemStore>();
Tfspreview.com now supports basic authentication which would eliminate IE being displayed at all. See here for details on how to set this up for your tfspreview.com and then use the username and password you configured.

Distinguish between local service account and impersonated client identity in a WCF ServiceLayer

we have a web frontend written in MVC which uses SSO and Windows Authentication and this frontend connects to a Backend WCF service layer configured to run with a specific AD service account.
we like this approach because the connections to the database server are trusted and we have no passwords in web.config and the WCF service layer is allowed to connect to SQL Server because the service account has proper rights on the DB Server, single end users don't and they should not.
what I am looking for now is a way to make the WCF service able to distinguish which user identity is connecting from the client and validate security rules on the application level (we use Visual Guard security Framework) but at the same time we have still the need to use the current service account when we use EF to connect to SQL.
what I did so far is the following,
when I create the WCF client in the web frontend:
using (((WindowsIdentity)HttpContext.Current.User.Identity).Impersonate())
{
var client = new RPPServiceInterface().GetRWSService();
...
}
from the moment I have introduced this call to Impersonate above, in the code below I can retrieve the client user and not the service account anymore:
[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
public List<RWSProgram> GetCedentsPrograms(int cedentID, int uwYear)
{
var currentSec = ServiceSecurityContext.Current;
...
}
what I would like to do is us both the client identity to validate security then somehow release that identity or have another way to impersonate back the service account in the service layer to open my SQL connection... Any idea? Am I doing anything wrong or misunderstanding the whole picture?
P.S. I already checked this one but did not help.... WCF service dual impersonation?
Thanks, Davide.
Is this what you are looking for? :
// ...Service operation code impersonating a client here
using (WindowsImpersonationContext processContext = WindowsIdentity.Impersonate(IntPtr.Zero))
{
// Database access stuff here
// Within the using block the client is no longer impersonated:
// context reverts to the identity running the service host process
// (I'm assuming this is what you call your service account)
}
// Ensuing code impersonates the client as previously...

Categories

Resources