ASP.NET Forms Authentication and Calling Web Service - asp.net

I have an ASP.NET application that uses Forms Authentication.
I need to call the Sharepoint search.asmx web service to retrieve a list of files from the network satisfying the search criteria (there's a good reason for me doing this outside of Sharepoint)
I'm not sure of the security information I need to pass the search.asmx. I've tried:
queryService.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials
queryService.ClientCredentials.Windows.AllowedImpersonationLevel = Security.Principal.TokenImpersonationLevel.Impersonation
-which works in my development environment as my user has access to the File Shares Sharepoint is accessing. What I can't understand, and can't infer from debugging or event viewers, etc. is what credentials are passed in the above code once I deploy this code on a server.
Will it pass the windows credentials of the user who opened the IE window prior to using forms authentication. Will it pass the credentials of the account that is running the asp.net components i.e. the account of the AppPool I'm running in, or will it pass something else?
I can't seem to get Sharepoint to return any files and I guess it's because the credentials being passed don't have access to the File Share.
Thanks
Andy

To get this working quickly you can access the SharePoint webservices with your username & password. This isn't the best solution long term obviously.
Set the Credentials property on the SharePoint webservice proxy to your username & password:
spProxy.Credentials = new NetworkCredential("username", "password", "domain");
You'll need to make sure the credentials property is set before you call the webservice.
I'm not a SharePoint expert (I've only used it as a developer), but I believe it only uses Windows authentication to secure the webservices. So forms authentication isn't going to help you out here if you want to access the webservices as the logged in user (unless you're validating the username & password manually with LDAP). ASP.NET Impersonation & Delegation only makes sense if you are using Windows authentication.
As stated by pseudocoder you might want to setup a special account to access SharePoint from the web server.

Related

How to get Window's logged in User Name and Password using ASP.NET WEB API 2

I am working on a Intranet application where i am calling a SAP service from a ASP.NET WEB API, Currently it is working fine with a HttpBasicAuthentication with a predefined user name and password. But now the requirement is to get the logged in windows user's user name and password through ASP.NET WEB API and pass it to the SAP service for authentication? Can anyone help me on this?
1) HttpBasicAuthentication won't apply in this case.
2) Use identity impersonate via the web.config tag (ref Identity Impersonate) to have the current user's identity taken up in api. However this will only work for Intranet based applications and not over internet. For Internet based, you will need to have Kerberos bridge (somewhat complicated) concept implemented.
3) In you app.start method, you need to set the current principal to windows principal.
Then you can have the user detail available..
Please note that you will not have the user's password available as OS protects that very very securely. You can get the user's Kerberos token though which your target system can auth against the AD being used.

How to Anonymously Authenticate between a VB.Net Desktop App and ASP.Net Web App

I'm looking for a way to pass some sort of credentials or Authorization token from a VB.Net Client to an ASP.Net web application that allows the Client to auto-login to our Forms-Authenticated website. If a user is logged into a local application, I want them to be able to view some web pages without having to login to the website as well. The credentials are not the same between the apps, but I would just like to pass some sort of encrypted token or key to the web page so I know they are coming from the desktop application. Is this possible without requiring a username and password login?
I also need to make sure this URL that is used cannot be simply copied and used from another location, so I'll need to include some sort of information in the encrypted value to know where it's coming from.
I know how to login the user with Forms Authentication and all that, just need to figure out the best way to secure this. Thanks!
OAuth is commonly used to allow desktop applications to access a user's private data on a web site. Since you're using .NET, I suggest you check out DotNetOpenAuth which includes sample OAuth web sites and client applications. It allows for this secure token to be passed that can tell your web site that the desktop app is the one making the requests and (usually) whose data is being accessed.
The best part about the OAuth solution is your desktop app never has to ask for the user's credentials. No credentials are in the URL. And if the desktop application is ever compromised (perhaps by the computer being stolen), the web site can kill the secure token the desktop app was using to cut off access without requiring the user to change their password.
You might want to look into issuing client-side certificates for these applications. Basically, you generate a certificate that you install with the client application and then on the server side, you check the ClientCertificate property of the HttpRequest instance exposed by the Request property on the current context.
Note that what you are doing is really a very bad idea, in that applications should never be assigned identity, only users. To that end, you should be authenticating each and every user that is using your app, not considering the application to be the identity. It's commonly considered a bad practice to do such a thing.
You can share credentials between the applications using ASP.NET Client Application Services.
Here are some resources:
Client Application Services
Client Application Services with Visual Studio 2008
Is your desktop app running on machines that are in the same domain as your web server (i.e. all in the same company)? If so, Integrated Windows Authentication is your easiest solution.
I think its best idea to use a web browser control inside the desktop application .
Then use the WebBrowser1.Document most probably
WebBrowser1.Document.Cookie
get if the user is singed in.
I also need to make sure this URL that
is used cannot be simply copied and
used from another location, so I'll
need to include some sort of
information in the encrypted value to
know where it's coming from.
If you store the encrypted value in a cookie or as a field in a form (POST request), then the credential is no longer in the URL and so it can't be easily copied (note that I said "easily").

Is it possible to get the Windows logon name with site running asp.net forms authentication?

I have a website with a large user base configured with asp.net 2.0 forms authentication. Before the user logs in via forms authentication is it possible to retrieve the windows login name/user account name on the machine they are using?
Many thanks
It certainly is possible--by adding another web application to your system. Here's roughly how I have done it:
Your primary web app uses Forms authentication. On the forms login page, any user that is determined to be on the local LAN (check IP address), redirect them to another app that uses Windows authentication. In this second app, you can determine the user (assuming the browser is configured to send credentials automatically to the zone in which your app resides), then set a cookie which your first app can read, and redirect the user back to the original app.
This does work.
This would only be possible if you were using Windows Authentication in your web application and then only if the user had logged in.
The kind of information you are after is not sent as part of the web request (quite rightly) and is therefore unknown to the web server.
Unfortunately no - if the user has not logged on, they are browsing anonymously, and are therefore unknown to the server. There is no way to identify them.
Once they're logged on, if you're using impersonation use WindowsIdentity.GetCurrent().Name. However, for forms authentication there's no direct way to ask the browser for their Windows credentials as they may not even be running Windows!
Not BEFORE no (not from the server).
Depending on the type of Auth you use, though, and the way the site is configured, you CAN get them to log in with their windows details.
See Mixing Forms and Windows Security in ASP.NET on Microsoft's MSDN.
The main difference with #TheObjectGuy answer is that instead of using 2 websites, this does all in a single website by configuring IIS to use the Integrated Windows authentication just in a "single" page (WinLogin.aspx).

DefaultCredentials in Accessing CRM / Sharepoint Web Services

I made an application that access CRM's web service. The problem is, when I deployed the dll into Sharepoint server, it returned error 401 unauthorized. Apparently the System.Net.CredentialCache.DefaultCredentials didn't work (my suspicion). Here's the code.
CrmSdk.CrmAuthenticationToken token = new CrmSdk.CrmAuthenticationToken();
token.AuthenticationType = AuthenticationType.AD;
token.OrganizationName = ORGANIZATION_NAME;
CrmService service = new CrmService();
service.Url = "http://crmserver:5555/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.PreAuthenticate = true;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
It goes vice-versa.
When I made application that access Sharepoint's webservice (coding the plugin) and deployed it to CRM server. It couldn't access the Sharepoint's web service. Unauthorized error. Here is the code:
Lists listService = new Lists();
listService.PreAuthenticate = true;
listService.Credentials = System.Net.CredentialCache.DefaultCredentials;
listService.Url = "http://sharepointserver/webname/_vti_bin/Lists.asmx";
My CRM server and Sharepoint server are in the same domain.
For both code, if I changed the credentials part into something like this then deploy it on server, it can run.
service.Credentials = new NetworkCredential("username", "password", "domain");
Still, I don't want to do this because it reveals user's password in the code. May anyone help me?
The IIS in both server doesn't allow Anonymous Access and it uses Integrated Windows Authentication.
Thank you
From my local computer, I can access the CRM web services or Sharepoint web services. I guess I'm authorized because the DefaultCredentials sent my credentials that its password is saved in the "Stored Username and Password" (Control Panel > User Accounts > tab Advanced > Manage Passwords)
This way, I don't have to type:
service.Credentials = new NetworkCredential("username", "password", "domain");
and my DefaultCredentials from my local comp is authorized to access the web services.
I tried to implement this on the Sharepoint server that access CRM web services. and..tadaa..it won't work. hahaha..
can we inject credentials to DefaultCredentials in server?
the last thing I want to do is to hardcode the useraccount (like the code above)
Could be that you need to be running Kerberos for authentication, but cannot be sure and it is a pain to setup just to check.
Have you verified that the default credentials are the same as those when you explicitly state them? It could be that the default credentails are those of another account that you wouldn't expect.
EDIT #1: Per the remarks for the DefaultCredentials property on MSDN:
DefaultCredentials represents the
system credentials for the current
security context in which the
application is running. For a
client-side application, these are
usually the Windows credentials (user
name, password, and domain) of the
user running the application. For
ASP.NET applications, the default
credentials are the user credentials
of the logged-in user, or the user
being impersonated.
You'll also want to ensure that the user accessing the CRM page (making the call to the SharePoint web service) can access the web service with their credentials and vice versa. If they can then it would seem more likely that some kind of impersonation is happening.
Edit #2: Assuming that you have access to both the CRM and SharePoint server you might take a peak into both the application and system logs. One or both should likely indicate a failed login and indicate which account attempted to access the resource (in this case the web services).
By using DefaultCredentials means the ASP.NET worker process or IIS worker process will take the credential of the user who run the IIS Application Pool.
so if your Dynamics CRM Application Pool is run under a user account Custom-CRM-Domain\JohnDoe, that means it will take the privileges under user account Custom-CRM-Domain\JohnDoe.
Please check the user account who run the application pool of the CRM\Sharepoint Application IIS Web application.
These are the steps to check the Application Pool:
Open the website -> Right Click -> Choose Properties
Select the Home Directory tab
Notice the Application Pool name at the dropdownlist below
Now, go to the Application Pools folder
Try to find the Application Pool name which has been listed in the step 3 -> Right Click and choose Properties
Select the "Identity" tab and you will find the user account who run the application pool
Hope this helps.
service.Credentials = System.Net.CredentialsCache.DefaultNetworkCredentials;
Try that.
Not familiar with Sharepoint, but can't you just store the connection information in a configuration and use built in tools for securing your web.config? Thats what I do.
https://web.archive.org/web/20211029043331/https://aspnet.4guysfromrolla.com/articles/021506-1.aspx
to be able use defaultcredentials, the user in active directory must be defined both in SharePoint and CRM and have enough privileges to do what you are doing with code.
And try to use sdk (crm have helper classes) instead of service definitions.
For fixing this issue you need to know first which user is running the App pool as the others said and if you need to use CredentialCache.DefaultCredentials then you have to add the user lets say svcadmin or the like into "Secondary site collection administrator" by running SharePoint central administration application . By that SP allows to the user which the credential has been passed through to access the things it needs.

ASP.NET Application to authenticate to Active Directory or SQL via Windows Authentication or Forms Authentication

I am in the process of writing an application that will need multiple forms of authentication.
The application will need to support authentication to Active Directory, but be able to fail back to a SQL Membership Provider if the user is not in Active Directory. We can handle the failing to the SQL Provider in code based on the username provided because the username will be a different format than the Active Directory username.
Is this even possible? What I mean is, can I use membership and use both ActiveDirectoryMembershipProvider and SqlMembershipProvider together or will I have to roll my own?
Another additional added complexity is that I would like to automatically authenticate my internal users based of Windows Authentication back to AD, but use Forms Authentication for users not on our internal network, or users that are using the SQL Provider.
These will most likely be separate servers, one internal, and the other external so I have a lot of planning to do to figure out the data replication, and how I will authenticate the AD users if they hit the outside server etc.
I am wondering what thoughts are out there as I start down this road. Is what I am wanting to do even possible without me rolling my own, or is there a way to mesh these together?
Thanks for the reply.
The reason I asked originally was because I was able to get this specific senerio working about 7 years ago using IIS to authenticate and then passing back the credentials to a Lotus Domino Server Web App. If the user was not authenticated via the Windows Authentication/ISS then Domino would handle the authentication. This was what I was looking to do here, but really couldn't think of a way to make it work in IIS.
As for the rest of your reply, I think you are on to the way that I will need to take. I have thought this through and tossed it around in my head a lot. The application will be somewhat different on the two servers anyway since there is going to be limited access to the data on the external server anyway. The fact that so much is going to be different already I may just treat these as two applications, thus negating the need to use two types of authentication in the same application anyway.
I am playing around with the idea already of writing my own authentication/login window for the external server, and if the user trys to log in with their AD credentials on the external server I will be able to detect that and redirect them to the internal server. If they are not on the local network or VPN'd in they will simply not get access. This part still has some thought process to go though so I am not sure.
As an additional thought - is there a way to pull just enough of AD into a SQL database to allow me to authenticate users to the SQL database from the external server using their AD credentials, without creating any security issues? I hope I am clearly typing what I am thinking....
Thanks again!
Tim
This is the way I've handled a similar situation based on this info:
Configured the application to use Forms authentication.
Set the LoginUrl to a page called WinLogin.aspx.
In WinLogin.aspx, use Request.ServerVariables["LOGON_USER"] to get the username then call FormsAuthentication.RedirectFromLoginPage( authorizedUserName, false ) to log them in. I guess you can manually check Active Directory as this point as well.
Create an html page that redirects to a page called Login.aspx
Login.aspx is your standard username/password login.
In IIS, Enable Integrated Authentication and Anonymous on the entire site, but deny anonymous access to WinLogin.aspx.
In IIS, set your 401 errors to the page created in step 3.
What basically happens is that when an unauthenicated user hits the site, they're redirected to WinLogin.aspx. Since anonymous is turned off, integrated security makes a check. If that passes, your custom code in WinLogin can run. If the integrated security check fails, a 401 error occurs. Your custom 401 page redirects to Login.aspx where the user can log in using their username and password with the SQL provider.
As far as I know, Web Applications are configured to use either Windows Authentication or Forms Authentication, but not both. Therefore, I do not believe it is possible to automatically authenticate internal users while requiring others to enter a username / password.
You could authenticate to Active Directory or a SQL user store via Forms authentication by using a custom provider. However, the AD users would still need to enter their username and password. Although I've never combined these two methods, I have used Forms authentication to authenticate against both sources at one time or another.
With that said, I think you may want to consider reducing the "flexibility" of your system. If you have an external facing server and an internal facing server, you could simply change the provider configuration on each copy of the application to go against a different source. Then, you could configure the internal one to use Windows (automatic) authentication and the external one to use Forms authentication.
IMHO, I believe that internal users should not be using the external server to access the application. If they are, they should have a user account stored in SQL, completely separated from their AD account. Basically, when someone accesses the application externally, they are acting as an external user, irregardless of their physical location.
Well, it is possible to use ActiveDirectoryMembershipProvider and SqlMembershipProvider, but this requires you design your log on page with your own code instead of the Login controls.
About the mix authentication (Windows and Forms), as far as I know only IIS 7 makes it easy and clean. See this post for details,
http://mvolo.com/blogs/serverside/archive/2008/02/11/IIS-7.0-Two_2D00_Level-Authentication-with-Forms-Authentication-and-Windows-Authentication.aspx

Resources