I have some sort of trouble, but i can't figure out where it can be. I have a search method. It uses filenet api and connects to server using admin credentials.
ClientContext.SetProcessCredentials(new UsernameCredentials(login, password));
var connection = Factory.Connection.GetConnection(storeUri);
var domain = Factory.Domain.GetInstance(connection, null);
var store = Factory.ObjectStore.FetchInstance(domain, storeName, null);
return store;
At target system it works fine, when i run console application. But when i run it at asp.net web site i got
"The requester has insufficient access rights to perform the requested operation." error. Who is requester at this point?
When you're running the application through a console, the user you are logged in as is used i.e. this is you and you probably have admin rights on the machine.
When you run it through IIS, this will depend on which version of IIS you are using. Look at this question for more information. You'll either need to change which user the web site is running under or grant further permissions to the user (or group) that is currently configured.
Related
I'm working on an older web app that I did not originally build, but now maintain. It is a classic ASP app with ASPX pages mixed in.
The site is setup for Kerberos authentication and delegation, and that is working properly to other boxes (e.g. I can run a SQL query against a back-end server from an ASP page in the site and it connects using the front-end client's credentials properly). So SPNs are registered, delegation privileges are configured in AD, etc.
Now, the part I'm having trouble with is an ASPX page which invokes a remote WMI call to check on the status of an IIS website, using the \root\WebAdministration WMI namespace. The ASPX page is itself invoked by way of an XHR which resides in the client-side code of a different ASP page. The ASPX, when invoked, makes the WMI call, then Response.Write's back the necessary data, which the originating ASP page then utilizes to populate the page that the user sees. The problem is, I cannot get the IIS box to properly delegate the user's credentials to the back-end machine that its making the WMI call against.
This all works properly (including the constrained delegation), but only if I enable protocol transition. If I set the delegation on the middle-tier (IIS) box to use only Kerberos authentication, it fails (I get an anonymous logon attempt on the back-end box).
Now, I've done numerous packet captures on both the front-end client and the IIS box to see exactly what is going on here, and I can see several things:
The front-end client is properly getting its Kerberos ticket, and presenting it to the IIS box for authentication.
The IIS box is accepting the Kerberos ticket from the client.
However, the IIS box is not using the ticket received from the client as the "evidence ticket" that it should be presenting to the KDC in order to obtain a service ticket to access the back-end service on behalf of the front-end user. Instead, the IIS box is using a S4U2Self call to the KDC to obtain a ticket on the front-end user's behalf for itself, then using that ticket in the subsequent S4U2Proxy call to try and obtain the ticket to the back-end. This is where the problem lies.
The behavior noted above is why this works when protocol transition is enabled, and does not work when it is not.
I cannot figure out for the life of me, why the IIS box feels the need to obtain a TGS for itself to use as the "evidence ticket" to get the ticket for accessing the back-end, instead of simply using the ticket presented by the client. There is nothing invalid about the client's ticket from what I can tell, and the client is establishing a Kerberos-authenticated connection with the web server just fine, so there should be no need for protocol transition here. I could enable it if really needed, but I really just want to know why its necessary (if there is valid reason and this is by design then so be it).
The IIS app pool is running as the built-in app pool identity, and the delegation settings are thus configured on the IIS machine account in AD. SPNs are registered for the site against the IIS machine account, and for the back-end services against those service and/or machine accounts, and the "allowedToDelegateTo" list is configured on the IIS machine account, allowing constrained delegation to the necessary services. The specific SPN we are trying to delegate creds to in this scenario is RPCSS/[machine] for the WMI call. I've verified via the packet capture that the SPN in the request matches the SPN in the A2D2 list exactly (of course, if it didn't, then it wouldn't be working when protocol transition was enabled anyway).
As for the actual WMI connection code, I've tried a few ways. One was something like this:
ConnectionOptions co = new ConnectionOptions();
// I did try ImpersonationLevel set to both Impersonate and Delegate, but I don't think I need
// Delegate here because I'm not delegating from the remote WMI machine to a different box; instead,
// I'm delegating from the IIS box to the remote WMI machine.
co.Impersonation = ImpersonationLevel.Impersonate;
co.Authentication = AuthenticationLevel.PacketPrivacy;
co.EnablePrivileges = true;
// Tried this for the Authority line because I noticed in the packet captures that the principal
// specified here becomes the SPN that is used in the S4U2Proxy request.
co.Authority = "kerberos:RPCSS/machine.domain.com";
ManagementScope ms = new ManagementScope(#"\\machine.domain.com\root\WebAdministration", co);
Then I also tried this:
ConnectionOptions co = new ConnectionOptions();
co.Impersonation = ImpersonationLevel.Impersonate;
co.Authentication = AuthenticationLevel.PacketPrivacy;
co.EnablePrivileges = true;
// I also tried this for the Authority line based on various other code examples for similar
// issues, but this resulted in an incorrect SPN being used in the request.
co.Authority = #"kerberos:DOMAIN\machine";
ManagementScope ms = new ManagementScope(#"\\machine.domain.com\root\WebAdministration", co);
I also tried the same as above, but without an Authority line, and the correct SPN was used in the request but it still didn't work.
Finally, I also tried this, with no ConnectionOptions object at all, hoping it would just pass on the default creds:
ManagementScope ms = new ManagementScope(#"\\machine.domain.com\root\WebAdministration");
Any help here on either how I can get this working without enabling protocol transition, or info on why this setup would require protocol transition, would be very much appreciated!
I have a MVC 5 application which uses OWIN and identity2.0 for authentication.
My application require mixed authentication:
for users not a domain lets say "dom1", they should see a form based page
for users on domain "dom1" they should be logged in via windows authentication.
I want to know how can I get the domain name of user without authentication, at the time when user first hit my Account/Login action.
I have used :
PrincipalContext pcontext = new PrincipalContext(ContextType.Domain);
var domainName = pcontext.ConnectedServer;
and
System.Security.Principal.WindowsIdentity context = System.Security.Principal.WindowsIdentity.GetCurrent();
var domainName = pcontext.Name;
BUT both of these shows domain name of machine where website is deployed and not of the client's domain.
Any help is much appreciated and please correct me if I am doing any blunder.
"without authentication"? You can't. The Windows authentication has to be completed before you can see the user's account.
This is because of how Windows authentication works:
The browser accesses the site anonymously.
IIS returns a 401 response
The browser responds by making the request again with the Windows credentials included
IIS verifies the credentials with the domain controllers
IIS passes the verified Windows credentials to your application.
The only time your application can see anything about the user's account is at step 5 - after the authentication is successfully complete.
The domain can be seen here
Environment.UserDomainName
Gets the network domain name associated with the current user.
Per the MSDN documentation:
The UserDomainName property first attempts to get the domain name component of the Windows account name for the current user. If that attempt fails, this property attempts to get the domain name associated with the user name provided by the UserName property. If that attempt fails because the host computer is not joined to a domain, then the host computer name is returned.
If you're not authenticated, you'll unfortunately see the host computer name. No way around this that I'm aware of.
You can also get the ip of the client's request here
HttpRequest.UserHostAddress
The tools
myWebApp: ASP.NET Core 1.1 MVC
myAuthApp with IdentityServer4
MS SQL Server 2012
IIS 8 on Win2012 Server
What we Want:
figure out what NTUser (intranet) is using the app to get userinfo from sqlserver-db (by searching the NTUserName) without any login dialog
What we have
one website (WinAuthApp) using asp.net impersonation (IIS Authentication) only to deliver NTUser-Name with return User.Identity.Name
and one website (our WebAPP) with Anonymous Authentication to get access to SQLServer with AppPool Identity. This WebApp redirects (when requesting without authentication token) to our AuthApp to check identity. AuthApp asks the WinAuthApp for the username and searchs the DB for permissionflags and builds an identity and a generates a token for it. with this authentication token it returns to WebApp and is now authenticaticated. External users give Name and Passwort and get a token to access WebApp.
Problems with this approach
when external users come to webApp and AuthApp asks WinAuthApp (with WindowsAuthentication configured) they get the NT-Login screen instead of WebApp's "Login Page for Externals". One contraint is: the intranetuser should NOT get a login dialog. (webApp has to answer to links and open the requested page immediately).
Summary
How can i configure my AuthApp (IdentityServer4) to have access to current NTUser (IF request comes from Intranet) but mainly working as AppPool-Identity (esp. for DB-Access)
I figured it out:
in Web.config set forwardWindowsAuthToken="true", and then set WindowsAuthentication true and asp.net impersonation false.
Then access to SQL-Server is done with appPool-Acount, and in the application context.User.Identity.Name gives user's NT-Account.
It wasn't too difficult but i always set WinAuth AND Impersonation synced. Don't know why.
I have an asp.net site on IIS using windows authentication (pass through) and I am trying to connect to the TFS API programmatically.
When I run it on my dev machine all is fine but once the site is on IIS I keep getting {"TF30063: You are not authorized to access http://mytfsserver."}
I have debugged the live site and it seems like it always takes the user as "NT SYSTEM" instead of the actual logged in user.
If I put my account details for the application pool it works as expected.
Any idea on how I can bypass this?
Code where it fails:
Uri collectionUri = new Uri(rootWebConfig.AppSettings.Settings["TFS_TEST_URI"].Value); //TEST ENV
tpc = new TfsTeamProjectCollection(collectionUri, CredentialCache.DefaultNetworkCredentials);
tpc.Authenticate();
workItemStore = tpc.GetService<WorkItemStore>();
You are hitting a standard active directory double hop authentication issue.
You have two options:
Username & password - if you ask the user to physically enter their username and password you can authenticate as them.
Kerberos - if you enable and configure Kerberos you can enable passthrough authentication. You need properly configured SPN: http://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx
I would go with kerberos tokens. It's a pain to configure but works a treat. Your only other alternative is to run your web app on the TFS server and bypass double hop.
I'm having trouble impersonating logged on user and then access unc files. I have tried using this sample code:
using System.Security.Principal;
...
// Obtain the authenticated user's Identity
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
// Start impersonating
ctx = winId.Impersonate();
// Now impersonating
// Access resources using the identity of the authenticated user
}
// Prevent exceptions from propagating
catch{}
finally
{
// Revert impersonation
if (ctx != null)
ctx.Undo();
}
// Back to running under the default ASP.NET process identity
If I try to access a file locally where the comment says Access resources using the identity of the authenticated user it works exactly as it should. If I however try to do the same thing with a file on a file server somewhere using UNC like \\ServerName\Share\FileName.txt it doesn't matter that the impersonated account has enough rights. The application throws an exception saying that the ASP.NET account does not have enough rights.
I have also tried to use unmanaged code to perform the impersonation and then it works! Local file or UNC, doesn't matter, works like a charm!
The problem is that you have to provide password and since it is the logged on users rights I want to check I can't provide that.
Does anyone know why the application behaves like this? Is it some configuration setting I need to set?
Web application runs with specific
identity, this identity is based on a
user account on the local machine or
domain.
The application uses this identity
when it accesses resources on disk or
services.
If the account does not have rights to
the resource, the web application will
not be able to use the resource.
Impersonation is where the web
application assumes a different
identity from the default
Impersonation can be configured to be
used for the web application on
startup, by adding an tag
to the web.config file. Impersonation
can also be implemented dynamically in
code, so that it can be turned on and
off as needed.
From ASP.NET Identity and Impersonation
So check you web.config and IIS Configuration and ensure that you're impersonating the correct user.