Basic authentication for the web service - asp.net

I'm having problems to set up the basic authentication for the web service.
I'm writing standard web service (not WCF) using .NET 4.0
In the web.config I have the following settings:
<configuration>
<system.web>
<identity impresionate="true" />
<authentication mode="Windows" />
</system.web>
...
</configuration>
The web service has one method:
[WebMethod(Description = "Returns currently logged in user.")]
public string WhoAmI()
{
return "You are logged in as: " + System.Threading.Thread.CurrentPrincipal.Identity.Name;
}
The test server is virtual machine located on the same domain as my machine. When I access it, I don't get anything for the CurrentPrincipal.Identity.Name.
I also tried to access the web service using the soapUI. I entered my username, password and domain but I still can't get it to work.
Any help would be appreciated.

On IIS (inetmgr) you can find Authendication Method window.(WebService1->Properties->Directory Security->Authendication Controls->Edit Button)
You can choose Authendicated access. (Diggest,Basic,Integrated Authendication)
After that changing your method will work as you want.

Does it work if you change impresionate to impersonate?

Related

When I am deploying by ASP.NET MVC application on IIS I am specifying my credentials in Identity as a setting in DefaultAppPool

Also if i don't give my credentials it gives some configuration file error.
I want AD authentication to take place. But it always picks my username when logged from different systems. How do I resolve it?
Is there any way I can make a user group and assign that to the Identity in DefaultAppPool or do I need to change the code for authentication as it is only taking the user from the Identity mentioned in DefaultAppPool?
The code that I am using to validate the user who logs in is as follows:
string groupName = ConfigurationManager.AppSettings["groupName"].ToString();
string domainName = ConfigurationManager.AppSettings["domain"].ToString();
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName);
UserPrincipal user = UserPrincipal.FindByIdentity(ctx,IdentityType.SamAccountName,System.Security.Principal.WindowsIdentity.GetCurrent().Name);
if (user != null)
{ //code as required }
code in web.config file:
<appSettings>
<add key="domain" value="EYDEV" />
<add key="groupName" value="Domain Users" />
</appSettings>
WindowsIdentity.GetCurrent() gets the credentials that your application is running under, not the current user.
You need to first enable Windows Authentication by adding this to your system.web section of your web.config:
<authentication mode="Windows" />
See Microsoft's documentation for more details (like making sure you have the right IIS features installed): https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/security/authenticating-users-with-windows-authentication-cs
Once that is setup, you can use User.Identity.Name in a Controller to get the username of the current user.

Asp.net delegation

I am making a .Net Web API that gets data by calling an SQL server. The user is authenticated via Windows Authentication (Kerberos). I would like the user credentials to be passed to the SQL server via delegation, but the SQL server sees an anonymous user.
This is what I have done:
IIS application:
Windows Authentication and asp.net impersonation enabled. Anonymous and forms authentication disabled.
Enable kernel mode authentication is checked.
Providers: Negotiate, Kerberos.
Use app pool credentials: True.
Application pool:
Managed pipeline mode: Classic.
Identity: Network service.
In AD, the computer the web server runs on is set to "Trust this computer for delegation to any specific service (Kerberos only)"
The connection string to the SQL server contains Integrated Security=SSPI;
Edit: In my web.config I have
<system.web>
<authentication mode="Windows" />
<identity impersonate="true" />
</system.web>
and
<security>
<authentication>
<windowsAuthentication enabled="true">
<providers>
<clear />
<add value="Negotiate" />
<add value="Kerberos" />
</providers>
<extendedProtection tokenChecking="None" />
</windowsAuthentication>
<anonymousAuthentication enabled="false" />
</authentication>
</security>
The generic HOST spn is set for the machine.
From the browser I access the web application via http://machinename.domain.net.
I would expect in this setup that my IIS application is run under the machine account?
When I catch a request in the debugger on the web server, I can see that WindowsIdentity.GetCurrent().Name is the account of the user browsing the web application and WindowsIdentity.GetCurrent().AuthenticationType is set to "Kerberos". So that should be good.
However WindowsIdentity.GetCurrent().ImpersonationLevel is only set to "Impersonate". I would have expected it to be set to "Delegate"?
When I make a request to the SQL server, I get "Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'" so obviously the user credentials are not passed to the SQL server.
I hope someone can see what I am doing wrong. I really need a push in the right direction.
For future reference if someone runs into the same issue:
The issue was that we tried from Chrome. It works in IE, but on Chrome the registry change mentioned in this post was needed: Kerberos delegation doesn't work in chrome
You should be able to set the Authentication to ASP.NET Impersonation within IIS. You will probably be required to set the following in your web.config file too, as part of < system.web> section.
<identity impersonate="true" />
This may be required in the < system.webServer> section to, although not always recommended due to security concerns.
<validation validateIntegratedModeConfiguration="false" />

Restricting Web Service Calls in Azure

I have a web site that makes calls to a web service. The web service currently restricts calls to be made only from the web site using IP restriction.
Now I am trying to move both sites to Azure Websites but I can no longer depend on a static IP address for calls from the web site because Azure Websites do not support static IPs for out-bound calls.
Azure Websites also do not accept client certificates.
How to I restrict calls to my web service to only be from my web site?
Since Azure Web Sites do not accept client certificates, I decided to take another approach. This solution uses ASP.NET's Forms Authentication and authorize a system user between services.
For this to work, each server must enable Forms authentication and be assigned the same machine key. I found it only works with the compatibility mode set to Framework45.
<system.web>
<machineKey compatibilityMode="Framework45"
validation="SHA1"
validationKey="14E2DFC..."
decryption="AES"
decryptionKey="93923..."/>
<authentication mode="Forms">
<forms loginUrl="/SecurityService.asmx?op=authenticate" />
</authentication>
<authorization>
<deny users="?" />
<allow users="System" />
</authorization>
</system.web>
Then generate and add a Forms authentication cookie to your web service (or any other HTTP call). Note that the Forms cookie had to be converted to a System.Net.Cookie.
var websiteService = new WebsiteService.WebsiteService();
websiteService.CookieContainer = new System.Net.CookieContainer();
var websiteServiceUrl = new Uri(websiteService.Url);
var authCookie = FormsAuthentication.GetAuthCookie("System",
false,
FormsAuthentication.FormsCookiePath);
var authenticationCookie = new System.Net.Cookie(FormsAuthentication.FormsCookieName,
authCookie.Value,
FormsAuthentication.FormsCookiePath,
websiteServiceUrl.Host);
websiteService.CookieContainer.Add(authenticationCookie);
Now all your authorizations can be configured in the authorization element in your web.config file as shown above.

Authentication mode=“Forms” causing redirect in WCF service

I have a WCF end point inside my .NET 4.0 Web Application project. Using the VS2010 WCF Test Client, I can connect to the service correctly. However when I go to use the service I get a generic error message:
The content type text/html; charset=UTF-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were:
When I looked at the requests on IIS Express I got the following:
Request started: POST http://machinename:port/Services/Services.svc
Request started: GET http://machinename:port/Services/Services.svc?AspxAutoDectectCookieSupport=1
Request started: GET http://machinename:port/(X(1)A(LKwosYYszAEkAAAAMDE2YzlmNWItNTZIOS00ZDY1LTgzOTAtNDIxNDgyOWZIYWViJ86TX46muUQoL_psmkZK2rgWbO41))/Services/Services.svc?AspxAutoDectectCookieSupport=1
Request ended: "http://machinename:port/Services/Services.svc" with HTTP status 302.0
Request ended: "http://machinename:port/Services/Services.svc?AspxAutoDectectCookieSupport=1" with HTTP status 302.0
Request ended: "http://machinename:port/Services/Services.svc?AspxAutoDectectCookieSupport=1" with HTTP status 200.0
So it seems like after POSTing to the service it is getting redirected to the standard web page for the service. Yet when I remove:
<authentication mode="Forms">
<forms cookieless="AutoDetect" loginUrl="~/Security/LoginClient.aspx" name="FORMAUTH" />
from the web.config it works. Any ideas what is happening? I have tried to remove the folder the service is in from authentication (http://stackoverflow.com/questions/5593720/authentication-mode-forms-causing-errors-in-wcf-end-point) but the issue still remains.
While this works using the Visual Studio Development Server (Cassini) when I run it through IIS Express 7.5 the same error occurs with or without authentication.
You have to provide authorization for your web services to be contacted anonymously in your web.config:
<location path="MyWebServices">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
This assumes that you keep all of your services in a folder called MyWebServices relative to the root of the application. You have to allow * or it will force a login for access.
I am experiencing the same issue as soon as I use the machinename instead of localhost in the service address. I did try to use a "baseAddressPrefixFilters" but without success.
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://XLSiteSampleD.aginsurance.intranet/PIXLSiteSample" />
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
I thought that option could have been to enable the aspNetCompatibility in the web.config
with the related attribute on the service :
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
But is does not the trick either :(
It only works with an address like http://localhost/VirtualSite/MyService.svc without a domain and without the baseAddressPrefixFilters !
V.

Why is ASP.NET ignoring my Membership connection string?

I have an ASP.NET app using built-in Membership functionality. As such, I have a connection string in my web.config that looks like this:
<add name="MembershipSqlServer" connectionString="Data Source=servername;Database=aspnetdb;uid=user;pwd=password;" />
When working on my dev machine, everything is peachy keen. But when I move things to the web server (which also happens to run the SQL Server), I get this error when User.IsInRole() is called:
System.Data.SqlClient.SqlException: Login failed for user 'NT AUTHORITY\NETWORK SERVICE'.
F$%*&!! Why is it attempting to connect in this way? Why isn't it using user/password from the connection string? Web.config is identical on dev and server, I am using the DB on the server during development.
OK, I figured it out... only 35 minutes. :P
Long story short: There are two parts to asp.net membership… a membership provider and a ROLE provider. Why you’d ever want these two things separated, I don’t know… But my web.config wasn’t specifying the role provider and connection string, so it was defaulting to the settings in machine.config (aka LocalSqlServer connection string).
So all this time, my app users were on the server... but the roles were stored in a local .MDF file in App_Data. Ugh.
What does the membership providers section in your web.config look like? Is it possible that you left out the connectionStringName attribute? In which case, I believe it would be trying to connect to the database on your local machine using integrated security.
The membership providers section in your web.config should look something like:
<membership defaultProvider="SqlProvider">
<providers>
<add
name="SqlProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="MembershipSqlServer"
...
/>
</providers>
</membership>
Do you see this <authentication mode="Windows" /> in your web.config? And your other connectionString uses Integrated Security=True; On your Sql server in order to use windows authentication you must have a Login(on the server) for the windows user or group as well as have an associated user in the database.
The simple but not suggested fix would be to create a login for 'NT AUTHORITY\NETWORK SERVICE'
on you sql server and then a user in your specific database for that maps to that login.
The secure way is to do this for each of the network security groups that need to access the sql server so you can manage the group permissions independently.
i think the answer is that :
public static string ConnectionString(SPSite site)
{
var connectionStringField = BaseMembershipProvider(site).GetType().GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
if (connectionStringField != null)
{
return connectionStringField.GetValue(BaseMembershipProvider(site)).ToString();
}
else
{
return "";
}
}
it worked for me with out any Error
thanks babania

Resources