Force ASP .Net Web API to block HTTP requests with Error (403) - rest

I would like to configure my project to not allow http requests with the following restrictions:
It must be a global restriction for all APIs (via web.config, script in the installer, etc.)
It must be hard coded(not pressing "Require SSL" on the APP in the IIS)
No "redirect"- just return error (403)
my ideal option would be to configure "Require SSL" by a script which runs in the installer.

This can be accomplished by writing a simple ActionFilter that inspects the request and responds when the scheme is not set to ssl. A very minimal implementation may look something like:
public class RequireHttpsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}
}
To make this apply everywhere, you'll likely want to register it as a global filter in the WebAPI configuration when your application is bootstrapping. That would look something like:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new RequireHttpsAttribute());
// ... More configuration ...
}
}
If you search the web a bit, you can find many examples of similar filters with more robust logic that may better meet your needs.

Related

How to enable Cross Origin Resource Sharing (CORS) in a Fantom / afBedSheet REST service?

I am developing a REST API with Fantom and afBedSheet. I need to allow cross-origin resource sharing so that I can call my RESTful services via AJAX from the UI which runs on a different web container on a different port.
I am currently doing this in request handler methods:
res.headers["Access-Control-Allow-Origin"] = "http://localhost:8080"
But as the API grows and the number of request handlers grow, it is no longer practical. I'm wondering how can I inject that header in every response. I have Googled the question but only found a reference to a document from a very old version of afBedSheet which doesn't seem relevant anymore. Can anyone provide an example, please?
CORS has to be set up manually but as mentioned, it's not that difficult. Anything that becomes repetitive in request handler methods can usually be squirrelled away somewhere, and setting HTTP response headers is no different. These can be set via BedSheet Middleware:
using afIoc
using afBedSheet
const class CorsMiddleware : Middleware {
#Inject private const HttpRequest req
#Inject private const HttpResponse res
#Inject private const ResponseProcessors processors
new make(|This|in) { in(this) }
override Void service(MiddlewarePipeline pipeline) {
// echo back in the response, whatever was sent in the request
res.headers["Access-Control-Allow-Origin"] = req.headers["Origin"]
res.headers["Access-Control-Allow-Methods"] = req.headers["Access-Control-Request-Method"]
res.headers["Access-Control-Allow-Headers"] = req.headers["Access-Control-Request-Headers"]
// deal with any pre-flight requests
if (req.httpMethod == "OPTIONS")
processors.processResponse(Text.fromPlain("OK"))
else
pipeline.service
}
}
Note that the above will enable CORS on all requests - handy for dev, but for live code you should be more choosy and validate any given Origins, Methods, and Headers.
BedSheet Middleware should be contributed to the MiddlewarePipeline service:
#Contribute { serviceType=MiddlewarePipeline# }
static Void contributeMiddleware(Configuration config) {
config.set("myApp.cors", config.autobuild(CorsMiddleware#)).before("afBedSheet.routes")
}
Note that CorsMiddleware is inserted into the pipeline before BedSheet routes to ensure it gets executed.

Hystrix getting access to the current execution state within fallback

I successfully configured spring-cloud (via spring-cloud-starter-hystrix) to wrap a call to a service.
This all works fine and looks like the following:
#Component
public class MyService {
#HystrixCommand(fallbackMethod = "fallback")
public void longRunning() {
// this could fail
}
public void fallback() {
// fallback code
}
}
My question now is, I would like to log some statistics about the execution error in longRunning()
Trying to access HystrixRequestLog.getCurrentRequest() within the fallback method throws
java.lang.IllegalStateException: HystrixRequestContext.initializeContext() must be called at the beginning of each request before RequestVariable functionality can be used.
I am looking for a simple way to log the exception of longRunning if the fallback is called.
testing with v1.0.0.RC2
To see a stack trace you can just enable DEBUG logging in com.netflix.hystrix.
As far as I can tell, to use the HystrixRequestContext the caller of MyService has to call HystrixRequestContext.initializeContext() before using the service. That sucks, so if anyone has a better idea, I'm interested.
Starting from Javanica v1.4.21, it allows fallback method to have an argument of Throwable type for accessing the command execution exception like so:
public void fallback(Throwable e) {
// fallback code
LOGGER.error(e.getMessage());
}
To get this feature, your build config needs to override the older version of Javanica pulled in by Spring Cloud.

Securing Entities with Claims Based Authorization in Web Api 2 OData Endpoint

Given the following Controller
namespace MyNamespace.Api.Controllers
{
[Authorize]
public class AccountController : ODataController
{
private Entities db = new Entities();
// GET odata/Account
[Queryable]
[ClaimsPrincipalPermission(SecurityAction.Demand, Operation = "Read", Resource = "Account")]
public IQueryable<Account> GetAccount()
{
return db.Accounts();
}
...
}
}
I override the ClaimsAuthorizationManager.CheckAccess(...)
public class AuthorizationManager : ClaimsAuthorizationManager
{
public override bool CheckAccess(AuthorizationContext context)
{
var resource = context.Resource.First().Value;
var action = context.Action.First().Value;
return Policies.Validate(resource, action);
}
}
This is useful only to the point where I can check whether or not the Current Principal in general can Read Account. However, if I'd want to check which accounts a certain user is allowed to Read, I am lost.
Let's say I have a Manager user who should be able to read all Accounts for which he is a manager for whereas a non-manager user should be able to read only their own account.
Is there a best practice for this or have you done something like this previously and give me a few hints to look for?
I do not use ClaimsPrincipalPermissionAttribute because I cannot pass any dynamic parameters to it like requested Account from your sample.
Have a look at the book "Pro APS.NET Web API Security" page 97. They suggest to invoke AuthorizationManager from your controller action implementation by code new IdentityConfiguration().ClaimsAuthorizationManager.CheckAccess(context), where context is constructed manually so you can pass Account requested (for example) as Resource to check it in your AuthorizationManager implementation.
Also have a look at pluralsight training "Introduction to Identity and Access Control in .NET 4.5". There are also some info about how to implement claim-based security in Web API.
Now I am in progress of implementing the security you are talking about and I am interesting in the subject too.
My case is: role Administrator is assigned by Country, every Administrator can see entities only related to the countries they have access to.
UPDATE: After several projects I forgot about Claims-based security as this is extremely difficult way to make security checks. Today I use decorator pattern where all the security checks are done. It appears to be very easy to implement security even in OData Controllers like this:
public IQueriable MyQuriableEntitySet
{
get{ return implementationWithoutSecurity.MyQuriableEntitySet.Where(e=>e.Country.Code = currentUser.AssignedTo.CountryCode || currentUser.IsSuperAdmin); }
}

How to connect To TFS EventService with SOAP in easy steps

I can't seem to find how to connect to the TFS EventService SOAP, I think I should make a service which gets called by TFS with stuff as parameters with which I can work with...
But I'm not finding anything like that on the internet.
The only thing I've found is this: http://msdn.microsoft.com/en-us/magazine/cc507647.aspx
Which seems old and deprecated.
I'm using tfs2012 and vs2012.
#Edit: The idea is to hook up to the WorkItemStatusChange and to the CheckIn events.
I use an interface for my services (same for TFS2010 and TFS2012)
using System.ServiceModel;
using System.ServiceModel.Web;
namespace TFS_Event_Services
{
[ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
public interface ITFS_Event_Services
{
[OperationContract(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify")]
[XmlSerializerFormat(Style = OperationFormatStyle.Document)]
[WebInvoke(Method="Notify")]
void Notify(string eventXml, string tfsIdentityXml);
}
}
So my .svc looks like this:
namespace TFS_Event_Services
{
public class TFS_Event_Services_2012 : ITFS_Event_Services
{
public void Notify(string eventXml, string tfsIdentityXml)
{
//do something with the Event
}
}
}
The .svc markup:
<%# ServiceHost Language="C#" Debug="true" Service="TFS_Event_Services.TFS_Event_Services_2012" CodeBehind="TFS_Event_Services_2012.svc.cs" %>
After creating your web service you need to publish it on some IIS which is the target of TFS alert soap call, of course.

adding http headers in call to SoapHttpClient service

I have to consume a service provided by one of our partners. I was given little direction, but was told the security was to be PasswordDigest. I looked it up and immediatly saw lots of references to WSE, so off I went. It was very easy to implement and in no time I had a standard WSE user token using PasswordDigest sitting in the SOAP headers of my messages.
When we started testing today I was immediatly told (by the error message) that things weren't right. Turns out, out partner doesn't look in the SOAP header, but rather wants the security info in the http header.
I have seen lots of articles on how to add custom http headers to a proxy class, but my proxy inherits from SoapHttpClientProtocol which doesn't have a headers collection to add to. I was looking at making a raw httpWebRequest, but I have a specific method to access that has some complex parameters to deal with (and besides it feels like going backwords).
What is the best way to add custom http headers to a service proxy class that doesn't have a GetWebRequest method?
For reference:
Proxy class decleration:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.3053")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="MtomServiceSoap11", namespace="http://ws.xxxxxxx.com/")]
public partial class MtomServiceService : System.Web.Services.Protocols.SoapHttpClientProtocol {
Target method I need to call:
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElementAttribute("uploadDocumentResponse", Namespace="http://ws.edsmtom.citizensfla.com/")]
public uploadDocumentResponse uploadDocument([System.Xml.Serialization.XmlElementAttribute(Namespace="http://ws.xxxxxxx.com/")] uploadDocumentRequest uploadDocumentRequest) {
object[] results = this.Invoke("uploadDocument", new object[] {
uploadDocumentRequest});
return ((uploadDocumentResponse)(results[0]));
}
}
The actual call to the Service is simple. The objects being pass in are not:
request.criteria = docCriteria;
request.document = document;
var result = service.uploadDocument(request);
Thanks.
It figures that 30 minutes after posting I would stumble across the answer. While the proxy class decelaration does not create a GetWebRequest method, its base class System.Web.Services.Protocols.SoapHttpClientProtocol has it and it can be overridden.
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
var request = base.GetWebRequest(uri);
request.Headers.Add("blah", "blah"); // <----
return request;
}