I have an ASP.NET MVC 3 application with a self hosted ServiceStack API that provides the data. After I added the API location path in Web.Config the API is callable by my code and works well:
<location path="api">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
The problem I have is that when the application is running the API is accessible via the browser - I can simply type http:\localhost:xxxx\api into the browser. What would be a good approach to restricting access to my self hosted API so that I can continue to call it within the MVC 3 application but prevent users from accessing the API via the browser?
Note that at some point in the future I will want to expose some areas of the API to make them publicly accessible.
Note: the Authorization and Authentication support built-into ServiceStack is independent and decoupled from ASP.NET's Authentication.
You can generically restrict access to all your services by inheriting from a base class which contains one or more of:
[Authenticate] - Only allow access to Authenticated users
[RequiredRole] - Only allow access to users in the specified roles
[RequiredPermission] - Only allow access to users with the specified permissions
Note: These attributes also work in your MVC Controllers that inherit from ServiceStackController or Controllers marked with the [ExecuteServiceStackFilters] attribute.
You can inspect a MVC + ServiceStack demo that uses these attributes in the Social Bootstrap Api example project.
Another way you can generically restrict access is by registering a global Request filter which get executed on every request.
One possibility is to use a specific user for accessing the API:
<location path="api">
<system.web>
<authorization>
<allow users="api_user" />
</authorization>
</system.web>
</location>
Then configure your API to be accessible only by the api_user. This way any other authenticated user in the browser won't be able to access this API. In your ASP.NET MVC 3 application you could create an authentication ticket with the given user before sending an HTTP request to the API.
Also notice that using the <location> tag in web.config to control authorization in ASP.NET MVC application is a very bad idea. The reason for this is that you are relying on some url (api). But ASP.NET MVC works with routes. So you should be using the [Authorize] or a custom authorization attribute to decorate the corresponding controllers/actions that you want to protect. This way your authorization is no longer dependent on your routing configuration.
Another possibility is to use a custom authoriza attribute and implement an access token.
Related
I have the following structure for my web application:
In my root web config, not in the Areas/Admin/Web.Config I have the following:
<location path="Areas/Admin">
<system.web>
<authentication mode="Windows"></authentication>
<authorization>
<deny users="*"/>
</authorization>
</system.web>
</location>
I have my own authentication working on the main root of the web site no problems by using the [Authorize] tag.
Now for the Areas/Admin I'd like to use Windows Authentication.
In IIS (Server 2008 R2 Machine), I have the Admin folder configured as an application:
And when I click on Areas/Admin in IIS, under Authentication, I have Anonymous disabled, and Windows Authentication Enabled.
However, when I attempt to access this folder via the web site, it does not prompt me for my domain username/password. It just loads up the page.
If I go to www.website.com/Areas/Admin, it then prompts me for the username/password. But I need it to use the AreaRegistration, and have it prompt when I go to www.website.com/Admin.
I've been able to configure an entire site as Windows Authentication, and that works like a charm.
Any thought to lead me in the right direction? Or, if you need more information, please leave me a comment and I will be more than happy to give you what I can.
From doing research, I found that the only way to make this work, is to create a 2nd "admin" site which runs as an application under the main site. Doing so, allowed me to setup permissions on that site.
I have a developed a Restful webservice using Asp.net WebAPI and used the windows authentication in the web.config file. This WebService is called by inhouse windows application in the internal network. Now the problem is when i send the request from
the IE browser to the webService it authentication and authorization works fine.
but when i send the request through the Widows application the user are not authenticated.
scenario :
When i use below config, The Request from the webbrowser is authenticated correctly, But request from windows application are not authenticated even if users are in correct AD group with correct roles.
<authentication mode="Windows"/>
<authorization>
<allow roles = "someGroup1"/>
<allow roles = "Somegroup2"/>
<deny users="*" />
</authorization>
what could be the problem please provide any suggestion.
I found out the problem, The windows client was not sending the User Information to the Webhost so the authentication and Authorization was failing. Since I was using NTML Authentication, so to resolve this issue i had to add a Authenticator to the restClient as below:
var client = new RestClient();
client.BaseUrl = ServiceUrl;
client.RemoveHandler("application/json");
client.RemoveHandler("text/json");
**client.Authenticator = new NtlmAuthenticator();**
I have an MVC3 Intranet app that uses Windows authentication. I'm now using a third party service that will make notification calls to my app. I've already created a listener for these API calls but not sure how I can allow anonymous access to that single view in my app.
My IIS7 settings are as follows:
Anonymous - Enabled <---------- Use Domain User
ASP.NET Impersonation - Disabled
Basic Authentication - Disabled
Digest Authentication - Disabled
Forms Authentication - Disabled
Windows Authentication - Enabled - HTTP 401 Challange
Additionally, in my web.config file, authentication mode is set to Windows.
With that said, is there a way to allow anonymous access to a single view in my MVC app?
Where path is your end url, add this your web.config.
<location path="MyController/MyAction">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
Or decorate the action with AllowAnonymousAttibute http://msdn.microsoft.com/en-us/library/system.web.http.allowanonymousattribute(v=vs.108).aspx.
has anyone implemented signgle sign on in MVC? Can anyone give me any example for single sign on in MVC.
I've implemented a SSO solution between multiple ASP.NET MVC applications hosted on the same parent domain (app1.domain.com, app2.domain.com, ...) by using Forms Authentication and setting the domain property of the cookie in web.config of all applications:
<forms
name="ssoauth"
loginUrl="/login"
protection="All"
timeout="120"
requireSSL="true"
slidingExpiration="false">
domain="domain.com"
/>
When you set the domain property of the cookie, this cookie will automatically be sent by the client browser to all applications hosted on this domain and will be able to authenticated the user automatically.
If you want to implement a cross domain SSO using Forms Authentication here's what you could do:
The user navigates to foo.com and signs in. The application hosted on foo.com uses standard Forms Authentication, nothing fancy.
The user decides to go to bar.com and clicks on a link that you created. This link could contain a token parameter which will contain the encrypted username. This encryption could be done using the machine keys and look something like this: https://bar.com?token=ABC.
The application hosted on bar.com receives the request and because it uses the same machine keys as the other application it is capable of decrypting the token and fetching the username. Then it simply signs in the user by emitting an authentication cookie locally and the user is automatically signed in bar.com.
Below is an example for SSO for websites sharing same domain
http://www.codeproject.com/Articles/27576/Single-Sign-on-in-ASP-NET-and-Other-Platforms
Please see my answer here. Basically you need to set Authentication mode to windows on web.config and use HttpContext class to retrieve user identity which takes data from Active directory
https://stackoverflow.com/a/40938106/950944
I have a WCF service which needs to be called from client side(ajax call).
I want to use ScriptManager on ASPX page to add a ServiceReference to the WCF service (or) JQuery ajax call to the WCF service. I want to deny anonymous users accessing the WCF service. Is there any way to do user authentication before calling a service method from JavaScript? how to secure my WCF service calls from client side?
There are a number of things you can do to secure your WCF services. Probably the easiest way is if your services are already part of the existing overall ASP.NET application is to enable ASP.NET Compatibility Mode for your services. If your ASP.NET app uses authentication to validate users (e.g. forms authentication) and you are enabling that via a session cookie, then ASP.NET Compatibility Mode does most of that work for you.
By default, this is disabled, but you can enable it with an addition to your web.config:
<system.serviceModel>
...
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
...
</system.serviceModel>
This will enable compatibility mode for all your services in your application. You can also enable this on a service by service basis by setting the web.config value and also using the AspNetCompatibilityRequirements attribute on your service class not the interface):
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class FooService: IFooService {
}
When you enable this setting, you have access to HttpContext.Current (like an ASP.NET page) and it will also enforce that a user must be authenticated before accessing the .svc file (just like you have to be authenticated before accessing any .aspx file). If you try to access a .svc file without being authenticated, and you're using forms authentication, the caller will be redirected to the default login page and, after successful authentication, will be redirected to the .svc file.
This suggestion makes a few assumptions:
your services are in an ASP.NET application;
you're using some type of ASP.NET authentication (like forms authentication) to validate users' credentials and persist a validation ticket in a cookie;
This suggestion, while maybe not the most secure or robust, is probably the simplest to at least get up and running and secure your site to a reasonable degree.
Here's a good MSDN library intro article on ASP.NET compatibility mode.
If this works, perhaps the next step is to look into something like HMAC authentication (which involves a bit more work and the coordination of secret keys - but it's definitely more secure IMHO). Here's a nice walk-through of implementing it - http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/22/how-to-implement-hmac-authentication-on-a-restful-wcf-service.aspx
I hope this helps. Good luck!!
I'm not sure if this will help but I placed a layer between my WCF and webapp. I'd make an AJAX servicereference call to a local asmx. This came under the protection of the forms authentication ticket. The asmx would then do any further security checks (if that specific user making the call was allowed to request that data or shape the data based on the user) and then forward the call on to my WCF service.
This way my service layer did not need to know about the users for each app accessing it and only had a concern for delivery of requested data.
The asmx webservice took the responsibility of security.
Then I made the WCF hosted in IIS using WAS and only allowed Windows Auth access for the identity that the webapp app pool was running as.
So:
ASPX -> ASMX WebService -> WCF
I think that would give you the control/separation and security you are asking for?
for WCF web http service The only way to secure a Web endpoint is to expose it through HTTPS, using transport security. When using message-based security, security information is usually placed in SOAP headers and because the messages sent to non-SOAP endpoints contain no SOAP envelope, there is nowhere to place the security information and you must rely on transport security.