Merhaba, siteme hoşgeldiniz.

Paylaşımları kaçırmamak için bültene kayıt olmayı unutmayın.

Salı, 07 Mart 2017 / Published in Uncategorized

Download XamlChessBoard_X11_32.zip Mono solution including full source and executable Download XamlChessBoard_X11_64.zip Mono solution including full source and executable  Download XamlChessBoard_Win10.zip Visual Studio 2015 solution including full source and executable

Introduction

This article is a case study, how to write a MVVM (Model View ViewModel) design pattern based X11/Windows (cross platform) application (utilizing the DrawingBrush including offset and repeating tiles) with XAML using the Roma Widget Set (Xrw). The Roma Widget Set is a zero dependency GUI application framework for X11 (it requires only assemblies of the free Mono standard installation and libraries of the free X11 distribution; it doesn’t particularly require GNOME, KDE or commercial libraries) and is implemented entirely in C#.

This article continues the works Writing a XAML dialog application for X11, Writing a XAML ribbon application for X11, Writing a XAML application for X11 with massive data binding and zero code, Writing a XAML calculator application for X11, Writing a XAML application with geometry objects (shapes) for X11, Writing a XAML application for X11 with UserControls, Writing a XAML 7 segment LCD display UserControl for X11 and Windows and Writing a XAML Minesweeper game for X11 and Windows. As far as i know, this (utilizing the Xrw) is the first attempt to use XAML for X11 application development after the abandonment of Moonlight.

Neither the Roma Widget Set nor the XAML implementation are complete. This sample application is intended as a more complex ‘proof of concept’ and checks out if and how it is possible bo create MVVM design pattern based X11/Windows (cross platform) application with XAML.

Since this ninth attempt to use XAML for a X11 application development has been successful, other articles about XAML using the Roma Widget Set on X11 will follow centenly.

Background

The Motivation and the general Concept to use XAML for X11 application development are already explained in the Writing a XAML dialog application for X11 article.

Some major enhancements (System.Windows.Media.GeometryGroup, System.Windows.Media.DrawingBrush and X11.X11DrawingBrushInfo) have been made and some bugs of the Xrw XAML wrapper have been fixed for this demonstration application after the release of Xrw version 0.9.

Focus

Since the previous eight articles "Writing a XAML …" already demonstrated several MVVM techniques, this article shall demonstrate that with XAML for X11

  • a windows compatible DrawingBrush can create easily a nice looking chess board utilizing drawing offset, repeating tiles and color gradient.

Using the code

The sample application was written with Mono Develop 2.4.1 for Mono 2.8.1 on OPEN SUSE 11.3 Linux 32 bit EN and GNOME desktop. Neither the port to any older nor to any newer version should be a problem. The sample application’s solution is build with MONO/.NET 3.5. It consists of two projects (the complete sources are provided for download):

  • XamlChessBoard contains the source code of the sample application.
  • XamlPreprocessor contains the source code of the XAML preprocessor.

The sample application is also tested with Mono Develop 3.0.6 for Mono 3.0.4 on OPEN SUSE 12.3 Linux 64 bit DE and GNOME desktop, IceWM, TWM und Xfce.

The only difference between the 32 bit and the 64 bit solution is the definition of some X11 specific data types, as already described in the Programming Xlib with Mono develop -Part 1: Low level (proof of concept) article.

The Xlib/X11 window handling is based on the X11Wrapper assembly version 1.0 (a library version 1.0 release candidate is included in this solution), that defines the function prototypes, structures and types for Xlib/X11 calls to the libX11.so. This assembly has been developed for the Programming Xlib with Mono Develop – Part 1: Low-level (proof of concept) project and has been advanced during the Programming the Roma Widget Set (C# X11) – a zero dependency GUI application framework – Basics project.

The GUI framework is based on the Xrw assembly version 1.0 (a library version 1.0 release candidate is included in this solution), that defines the widgets/gadgets and its wrapper classes used within the XAML code (that should be as near to the Microsoft® original as reasonable). This assembly has been developed during the Programming the Roma Widget Set (C# X11) – a zero dependency GUI application framework – Basics project.

The sample application implements a DrawingBrush drawingbrushBoard that utilizes its Viewport and TileMode properties to realize repeating tiles, a LinearGradientBrush to polish the look of the black fields and its parent Rectangle‘s Margin property to realize a border around the board (offset to the parent Canvas).

The Windows Visual Studio 2015 project of the sample application is completely based on the source code of the article DrawingBrush in WPF by Purushottam Rathore (many thanks for tis great idea to demonstrate DrawingBrush). The Linux/Unix (X11) Mono projects are derived from this source code.

Advice: To use the class library documentation shortcut (F1) from MonoDevelop, the "mono-tools" package has to be installed.

The images of the sample application show the chess board on several platforms.

The first image shows the sample application on OPEN SUSE 11.3 Linux 32 bit EN and GNOME desktop.

The second image shows the sample application on OPEN SUSE 12.3 Linux 64 bit DE and Xfce.

The third image shows the sample application on Windows® 10 64 Bit Edition.

The application window utilizes the System.Windows.Controls.Canvas as its root layout manager. It also defines the child System.Windows.Shapes.Rectangle and its System.Windows.Media.DrawingBrush used to fill the rectangle.

The layout is defined by the rectangle’s Margin property. The drawing brush size is 100px * 100px while the rectangle’s width and height are 400px * 400px. Therefore the drawing brush must be applied 4 times in x and 4 times in y to fill the rectangle entirely.

There is no functional difference between the X11 and Windows® 10 versions of the sample application, they share the same XAML code (except the margin values) and there is no code behind (so nothing can differ here).

Walk through

Main view file context

The XAML (MainWindow.xaml)

Here the complete code of the XAML file (X11 32 Bit MonoDevelop solution):

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ext="clr-namespace:System.Windows.ExtControls"
    x:Class="XamlChessBoard.MainWindow"
    Name="DigiClock" Title="Chess Board"
    Height="500" Width="500" Icon="XrwIcon16.bmp"
    Background="#FFDDDDDD">
  <Canvas Name="canvasRoot" Background="SkyBlue">
    <Rectangle Name="rectangleBoard" Width="400" Height="400" Margin="50,45,40,40">
      <Rectangle.Fill>
        <DrawingBrush x:Name="drawingbrushBoard" Viewport="0,0,0.25,0.25" TileMode="Tile">
          <DrawingBrush.Drawing>
            <DrawingGroup x:Name="drawinggroupBoard">
              <GeometryDrawing x:Name="geometrydrawingWhiteBackground" Brush="White">
                <GeometryDrawing.Geometry>
                  <RectangleGeometry x:Name="geometryWhiteBackground" Rect="0,0,100,100" />
                </GeometryDrawing.Geometry>
              </GeometryDrawing>
    
              <GeometryDrawing x:Name="geometrydrawingBlackForeground">
                <GeometryDrawing.Geometry>
                  <GeometryGroup x:Name="geometrygroupBlackForeground">
                    <RectangleGeometry x:Name="rectanglegeometryBlack1" Rect="0,0,50,50" />
                    <RectangleGeometry x:Name="rectanglegeometryBlack2" Rect="50,50,50,50" />
                  </GeometryGroup>
                </GeometryDrawing.Geometry>    
                <GeometryDrawing.Brush>
                  <LinearGradientBrush>
                    <GradientStop Offset="0.0" Color="Black" />
                    <GradientStop Offset="1.0" Color="Gray" />
                  </LinearGradientBrush>
                </GeometryDrawing.Brush>
              </GeometryDrawing>
            </DrawingGroup>
          </DrawingBrush.Drawing>
        </DrawingBrush>
      </Rectangle.Fill>
    </Rectangle>
  </Canvas>
</Window

The sample application doesn’t have any resources – the DrawingBrush is defined directly within the Rectangle‘s Fill property besause it is used/referenced only once.

To draw background and foreground with one single brush, background and foreground must be combined – and this is done within the DrawingGroup drawinggroupBoard.

While background is realized by just one white rectangle GeometryDrawing geometrydrawingWhiteBackground, the foreground GeometryDrawing geometrydrawingBlackForeground requires to combine two black rectangles – and this is done within the GeometryGroup geometrygroupBlackForeground.

To fill the chess bord (defined by the Rectangle rectangleBoard) entirely, the DrawingBrush must be applied 4 times in x and y. The Viewport property of the DrawingBrush defines no mapping offset for the DrawingBrush relative to the Rectangle to fill (see Viewport="0, 0, ...") and a scale of 25% with regard to the Rectangle size (see Viewport="..., 0.25, 0.25"). The TileMode property of the DrawingBrush enables drawing of repeated tiles.

The code behind (MainWindow.xaml.cs)

The corresponding C# code file of the main view is MainWindow.xaml.cs and it contains just the minimum code:

namespace XamlChessBoard
{
    /// <summary>Interaction logic for MainWindow.xaml</summary>
    /// <remarks>Idea based on article
    /// <see cref="http://www.c-sharpcorner.com/uploadfile/prathore/drawingbrush-in-wpf/"/>.</remarks>
    public partial class MainWindow : XrwXAML.Window
    {
        public MainWindow()
            : base (-1, -1)
        {
            InitializeComponent();
        }
    }
}

Main view model file context

There is no ModelView for the main view, because no Model is required.

Main model file context

There is no Model for the main view, because no data are to process.

Points of Interest

This is another XAML application for X11, fully compatible with Microsoft®, showing the main advantages of this approach (compared to an implementation with GTK+ or KDE): The 100% cross platform compatible GUI definition and the savings of code lines to create the GUI.

The use of DrawingBrush offers a very simple way to create a polished and this can be applied for X11 and Windows (cross platform).

History

The first version of this article is from 12. February 2017.

Salı, 07 Mart 2017 / Published in Uncategorized

Introduction

Browser security does not allow web pages to make AJAX requests to another domain. This prevention is called "same-origin policy". This prevents another site from reading sensitive data from another site.

Cross-Origin Resource Sharing (CORS) is a W3C standard. Using CORS, a Server can allow some cross-origin (domain) requests and reject others. CORS is more flexible and safer than the earlier techniques such as JSONP. In this article, we learn how to enable CORS in our ASP.NET Core Application.

Set up CORS in ASP.NET Core Application

To set up CORS in our Application, first we need to add "Microsoft.AspNetCore.Cors" dependency in our project.json file and using "dotnet restore", we can download the dependency.

  1. {  
  2.     "version""1.0.0-*",  
  3.     "buildOptions": {  
  4.         "preserveCompilationContext"true,  
  5.         "debugType""portable",  
  6.         "emitEntryPoint"true  
  7.     },  
  8.     "dependencies": {},  
  9.     "frameworks": {  
  10.         "netcoreapp1.0": {  
  11.             "dependencies": {  
  12.                 "Microsoft.NETCore.App": {  
  13.                     "type""platform",  
  14.                     "version""1.0.1"  
  15.                 },  
  16.                 "Microsoft.AspNetCore.Server.Kestrel""1.0.0",  
  17.                 "Microsoft.AspNetCore.Mvc""1.0.0",  
  18.                 "Microsoft.AspNetCore.Cors""1.0.0"  
  19.             },  
  20.             "imports""dnxcore50"  
  21.         }  
  22.     }  
  23. }  

Add the CORS Service in ConfigureServices method of startup class

  1. public void ConfigureServices(IServiceCollection services) {  
  2.     services.AddMvc();  
  3.     services.AddCors();  
  4. }  

Enable CROS in MVC

We can apply CORS in MVC per action, per controller or globally. MVC CORS Services are different from the Middleware CORS Service.

Apply CORS per Action

To specify CORS per action, add EnableCors attribute on top of the action. The EnableCors attribute accepts the policy name as an argument. We will learn CORS policy later on in this article.

Example

  1. [EnableCors("AllowSpecificOrigin")]  
  2. public IActionResult Index() {  
  3.     return View();  
  4. }  

Apply CORS per Controller

To specify CORS to the specific controller, add EnableCors attribute to the controller class. This applies the CORS to every action method of the controller.

Example

  1. [EnableCors("AllowSpecificOrigin")]  
  2. public class HomeController: Controller {}  

Apply CORS to entire Application

We can also enable CORS Application wide (globally). It applies CORS to all the controllers by adding CorsAuthorizationFilterFactory filter to the global filter collection in ConfigureService method of Starpup class.

Example

  1. public void ConfigureServices(IServiceCollection services) {  
  2.     services.AddMvc();  
  3.     services.Configure < MvcOptions > (options => {  
  4.         options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));  
  5.     });  
  6. }  

Disable CORS

Using DisableCors attribute, we can disable CORS for a controller or an action.

Example

  1. [DisableCors]  
  2. public IActionResult Index() {  
  3.     return View();  
  4. }  

Enable CORS in middleware

To enable CORS in middleware, we need to add the request pipeline, using UseCors extension method. It is similar to MVC and we can specify a cross origin policy when adding the CORS middleware, using the CorsPolicyBuilder class.

UseCors method has two overload versions, where the first one only accepts the poly name as an argument. Hence with this method, we need to pass the CORS policy name as a string.

Example

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {  
  2.     app.UseCors("AllowSpecificOrigin");  
  3. }  

The second method accepts the task of CorsPolicyBuilder type. By using the lamba expression, we can pass CorsPolicyBuilder object.

Example

  1. app.UseCors(option => option.WithOrigins("http://xyz.com"));  

CorsPolicyBuilder has a fluent API, so we can chain method calls.

Example

  1. app.UseCors(option => option.WithOrigins("http://xyz.com").AllowAnyMethod());  

CORS policy options

Following are the options, which we can set in CORS policy

  • Set the allowed origins

    Using WithOrigins method of CorsPolicyBuilder class and we can set one or more specific origins.

    1. app.UseCors(option => option.WithOrigins("http://xyz.com""http://abc.com"));  

    Using the code given below, we can allow all the origins.

    1. app.UseCors(option =>option.AllowAnyOrigin());  
  • Set the allowed HTTP methods

    Using WithMethods method of CorsPolicyBuilder class, we can set one or more specific methods.

    1. app.UseCors(option => option.WithMethods("GET", ”POST”));  

    Using the code given below, we can allow all the methods.

    1. app.UseCors(option => option.AllowAnyMethod());  
  • Set the allowed request headers

    Using WithHeaders method of CorsPolicyBuilder class, we can set one or more specific headers.

    1. app.UseCors(option => option.WithHeaders("accept""content-type""origin"));    

    Using the code given below, we can allow all the headers.

    1. app.UseCors(option => option.AllowAnyHeader());  
  • Set the exposed response headers

    The Browser does not expose the all the response headers to the Application.Using WithExposedHeaders method of CorsPolicyBuilder class, we can expose the additional headers.

    1. app.UseCors(option => option.WithExposedHeaders("x-custom-header"));  
  • Credentials in cross-origin requests

    The Browser does not send the credentials with a cross-origin request. In some case, we need to pass the credentials in a CORS request. The client must set XMLHttpRequest.withCredentials to true to send the credentials with a cross-origin request.

    The code given below is used to set the credentials in cross-origin requests.

    1. app.UseCors(option => option.AllowCredentials());  
  • Set the preflight expiration time

    The "Access-Control-Max-Age" header specifies how long the response to the preflight request can be cached. The code given below is used to set the preflight expiration time.

    1. app.UseCors(option => option.SetPreflightMaxAge(TimeSpan.FromSeconds(5000)));  

Define one or more named CORS policies and use the policy by name at run time

We can define set of CORS policies into the group and it is possible to select the policy run time. To achieve this, we need to add the group of the policy in ConfigureService method and select it at Configure method of Startup class.

Example

  1. public void ConfigureServices(IServiceCollection services) {  
  2.     services.AddCors(option => {  
  3.         option.AddPolicy("AllowSpecificOrigin", policy => policy.WithOrigins("http://abc.com"));  
  4.         option.AddPolicy("AllowGetMethod", policy => policy.WithMethods("GET"));  
  5.     });  
  6. }  
  7. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {  
  8.     app.UseCors("AllowSpecificOrigin");  
  9. }  

Summary

This article tried to explain how to enable CORS with ASP.NET Core Application for both MVC and middleware and different kind of CORS policies.

Salı, 07 Mart 2017 / Published in Uncategorized

In this article, we will see in detail about the ways we can customize our ASP.ENT MVC Application. Here, in this article, we will see three methods to customize our ASP.NET MVC Bootstrap templates.

  1. Using ASP.NET MVC Bootstrap Bundle template
  2. Using the Bootstrap Bundle Template CSS in our MVC Application
  3. Using Bootswatch Free themes for Bootstrap ASP.NET MVC.

Code Part

Using ASP.NET MVC Bootstrap Bundle template.

Installing Bootstrap Bundle

First, we need to download and install the Bootstrap Bundle template. For installing the Bootstrap Bundle template, open Visual Studio 2015 >Click on Tools>Click on Extensions and Updates. From the search type, “Bootstrap Bundle” and search. Click Download from the Bootstrap Bundle. Click on Install to install Bootstrap Bundle template. Getting started with Bootstrap Bundle template, close Visual Studio and reopen Visual Studio 2015.

Creating Bootstrap Bundle MVC application

Click on Bootstrap Bundle from left side template. Select Bootstrap Bundle MVC site, select your project path and enter your Application name and click OK. Here, we can see the Bootstrap Bundle template, which has 2 styles, “Bootstrap Example Layouts” and “Start Bootstrap Templates”.

Here, we will see how to get started with “Bootstrap Example Layouts”

Method 1

Bootstrap Bundle Style using Bootstrap Example Layouts

 

Select the Bootstrap example Layouts and click Next button.

Select your master layout style. Here, we have selected “Narrow Jumbotron” layout and click Next button.

Now, we need to select Theme for our Layout. Here, we can see group of theme has been listed in dropdown list.

Here, we have selected “Darkly” Theme for our Website.

Click Next and enter your site’s name in the text box and click Next.

Click finish. We can see our MVC Application has been created, press F5 to run our Application, we can see our MVC Application with new Bootstrap template. 


Method 2

 

Bootstrap Bundle Style using Start Bootstrap Templates

Click Next and enter your site name in the text box and click Next.

Click finish. We can see our MVC Application has been created. Press F5 to run our Application. We can see our MVC Application with new Bootstrap template.

Use Bootstrap Bundle template CSS in our MVC Application.

Method 3

Customizing ASP.NET MVC Application using Bootstrap Bundle templates

Now, we need to create our ASP.NET MVC Application and add Bootstrap Bundle templates in our MVC Application. First step is to create our ASP.NET MVC Application. Open Visual Studio 2015>Click Web > Select ASP.NET Web Application (.NET Framework)Select MVC and click OK to create our ASP.NET MVC Application.

After creating of MVC Application, run to view the default MVC Bootstrap template.

 

Now, let’s add our Bootstrap Bundle “Modern Business” template for our MVC Application. From our Bootstrap Bundle “Modern Business” Web project, select the CSS folder and we need to paste CSS folder to our new MVC Web Application project.

Paste the copied CSS folder to our Web Application.

In our _Layout.cshtml file, we need to add Bootstrap Bundle “css” style to change our template.

Use Bootswatch the Free themes for Bootstrap ASP.NET MVC.

Method 3

Customizing ASP.NET MVC Application using Bootswatch templates

Now, we need to create our ASP.NET MVC Application and add the Bootswatch themes in our MVC Application. First step is to create our ASP.NET MVC Application. Open Visual Studio 2015>Click Web > select ASP.NET Web Application (.NET Framework).

Select MVC and click OK to create our ASP.NET MVC Application.

After creating MVC Application, run to view the default MVC Bootstrap template.

Bootswatch provides free themes for Bootstrap. Bootswatch themes are easy to apply for our ASP.NET MVC Application. Visit

www.bootswatch.com

to see all the free themes for MVC Applications.

 

Here, we have selected “Superhero Theme” from the Website. We can see at the top menu both “bootstrap.css” and “bootstrap.min.css”. This is an open source and we can copy both “bootstrap.css” and “bootstrap.min.css” style codes and replace with our default CSS themes.

From the “bootswatch Superhero”, click on bootstrap.csss menu, copy the CSS style code from the link.

 

To apply the new theme with our default CSS, we need to open “bootstrap.css” from the content folder.

Replace the CSS style with our copied “bootswatch Superhero style”.

Similarly for “bootstrap.min.css” from the “bootswatch Superhero”, click on bootstrap.min.css menu, copy the CSS style code from the link. 

To apply the new theme with our default CSS, we need to open “bootstrap.min.css” from the content folder.

Replace the CSS style with our copied “bootswatch Superhero style”.

Run the Application and we can see our ASP.NET MVC Application has been applied with new Bootswatch Superhero theme.


Note

If you are good at design, you can also customize ASP.NET Default theme by yourself.

Salı, 07 Mart 2017 / Published in Uncategorized

Cross Site Request Forgery (aka CSRF or XSRF) is one of the most common attacks in which the user is tricked into executing an unwanted action through his browser on his behalf, in one of the sites he is currently authenticated.

ASP.Net Core contains an Antiforgery package that can be used to secure your application against this particular risk. For those who have used earlier versions of ASP.Net will see that things have changed a bit in the new framework.

This article is published from the DNC Magazine for Developers and Architects. Download this magazine from here [PDF] or Subscribe to this magazine for FREE and download all previous and current editions.

Brief CSRF overview

CSRF attacks rely on the fact that most authentication systems will store credentials in the browser (such as the authentication cookie) which are automatically sent with any requests for that specific website domain/sub domain.

An attacker can then trick the user through social media, emails and other ways into a malicious or infected site, where they can send a request on their behalf to the attacked or targeted site. If the user is authenticated on the targeted site, this request will include his credentials, and the site won’t be able to distinguish it from a legit request.

For example, hackers might send a link to the user which opens a malicious site. In this site, they will trick the user into clicking a button that posts a hidden form against the target site where the user is authenticated. The attacker will have forged this form to be posted against a URL like a fund transfers URL, and contain data like transferring some money to the attacker’s account!

Figure 1 visually depicts CSRF in action.

Figure 1: CSRF overview

It is important to understand that for these requests to be of any benefit to the attacker, they have to change some state in the application. Simply retrieving some data will be useless to them, as is for the users and their browsers who send the request and receive the response (even if they don’t know about it).

Of course the impact of the attack depends on the particular application and the actual user privileges, but it could be used to attempt fund transfers or purchases on behalf of the user, send messages on their behalf, change email/passwords, or do an even greater damage for administrative users.

OWASP maintains a page with recommended prevention measures for this attack which include:

  • Verifying the request origin
  • Including a CSRF token on every request (which should be a cryptographically strong pseudorandom value so the attacker cannot forge the token itself)

You can read more about this attack and the recommended technology agnostic prevention measures on the OWASP page.

The Open Web Application Security Project (OWASP) is a worldwide not-for-profit charitable organization focused on improving the security of software, that defines its core purpose as “Be the thriving global community that drives visibility and evolution in the safety and security of the world’s software.” You can read more about them on their about page.

How ASP.Net Antiforgery works

ASP.Net Core includes a package called Antiforgery which can be used to protect your website against CSRF attacks. This package implements the CSRF token measure recommended by the OWASP site.

More specifically, it implements a mixture of the Double Submit Cookie and Encrypted Token Pattern described in the OWASP cheat sheet.

This basically means that it provides a stateless defence mechanism composed of 2 items (or token set) that should be found on any request being validated by the Antiforgery package:

  • An antiforgery token included as a cookie, generated as a pseudorandom value and encrypted using the new Data Protection API
  • An additional token included either as a form field, header or cookie. This includes the same pseudorandom value, plus additional data from the current user’s identity. It is also encrypted using the Data Protection API.

These tokens will be generated server-side and propagated along with the html document to the user’s browser. The cookie token will be included by default whenever the browser sends a new request while the application needs to make sure the request token is also included. (We will see in the next sections how to do this)

A request will be then rejected if:

  • any of the 2 tokens is missing or have an incorrect format/encryption
  • their pseudorandom values are different
  • the user data embedded in the second token doesn’t match the currently authenticated user

An attacker won’t be able to forge these tokens himself. As they are encrypted, he would need to break the encryption before being able to forge the token.

If you are in a web farm scenario, it is important for you to check how the Data Protection API stores the keys and how they are isolated by default using an application identifier. This is important as when two individual instances of your web farm use different keys, they won’t be able to understand the secrets from other instances. Probably this isn’t what you want in your web farm and you will need to configure the Data Protection API so the instances share the same keys, and are thus able to understand secrets from each other. See the asp docs for an example with the authentication cookie.

Figure 2: Antiforgery in legit requests Vs CSRF attack requests

Additionally, whenever the tokens are generated by the server and included in a response, the X-FRAME-OPTIONS header is included with the value SAMEORIGIN. This prevents the browser from rendering the page in an iframe inside a malicious website that might attempt a Clickjacking attack.

The following sections will describe in detail how to enforce Antiforgery validation in your controller actions, and how to make sure the two tokens are included within the requests.

Using Antiforgery in your ASP.NET Core application

Adding Antiforgery to the project

The Microsoft.AspNetCore.Antiforgery package is already included as a dependency by Microsoft.AspNetCore.Mvc. Similarly, the required Antiforgery services are automatically registered within the DI container by calling services.addMvc() in your Startup.ConfigureServices() method.

There are still cases where you might want to manually add Antiforgery to your project:

  • If you need to override the default Antiforgery options, then you need to manually call services.AddAntiforgery(opts => {opts setup}) so you can provide your specific option settings. These options include things like the cookie name for the cookie token, and the form field or header name for the request token.
  • If you are writing an ASP.Net Core application from scratch without using the MVC framework, then you will need to manually include the Antiforgery package and register the services.

Bear in mind that this is just registering Antiforgery within your project and setting the options. It does not automatically enable any kind of request validation! You will manually need to do that as per the following sections.

Protecting controller actions

Even after Antiforgery has been added to your project, the tokens will not be generated, nor validated on any request, until you tell them to. This section describes how to enable the tokens validation as part of the request processing, while the following sections describes how to generate the tokens and make sure they are included in the requests sent by the browser.

You could manually add some middleware where you require an instance of IAntiforgery through dependency injection, and then call ValidateRequestAsync(httpContext), catching any AntiforgeryValidationException and returning a 400 in that case:

try
{
    await _antiforgery.ValidateRequestAsync(context);
    await next.Invoke();
}
catch (AntiforgeryValidationException exception)
{
    context.Response.StatusCode = 400;
}

However if you are using MVC, then there are Antiforgery specific authorization filters that will basically handle that for you. You just need to make sure your controller actions are protected by using a combination of the following attributes:

  • [AutoValidateAntiforgeryToken] – This adds the Antiforgery validation on any “unsafe” requests, where unsafe means requests with a method other than GET, HEAD, TRACE and OPTIONS. (As the other HTTP methods are meant for requests that change the server state). It will be applied globally (when added as a global filter) or at class level (when added to a specific controller class).
  • [ValidateAntiForgeryToken] – This is used to add the Antiforgery validation to a specific controller action or class. It does not take into account the request HTTP method. So if added to a class, it will add the validation to all actions, even those with methods GET, HEAD, TRACE or OPTIONS.
  • [IgnoreAntiforgeryToken] – Disables the Antiforgery validation in a specific action or controller. For example, you might add the Antiforgery validation globally or to an entire controller class, but you might still want to ignore the validation in specific actions.

You can mix and match these attributes to suit your project needs and team preference. For example:

  • You could add AutoValidateAntiforgeryToken as a global filter and use IgnoreAntiforgeryToken in rare cases where you might need to disable it for an “unsafe” request.
  • Alternatively you could add AutoValidateAntiforgeryToken just to your WebAPI-style of controllers (either manually or through a convention) and use the ValidateAntiforgeryToken in MVC-style of controllers handling many GET requests returning views with a few unsafe requests like PUT and POST actions.

Find the approach that works best for your project. Just make sure the validation is applied on every action where you need it to be.

Now let’s take a look at how to make sure the tokens are included within the requests sent by the browser.

Including the tokens in server side generated forms

For the antiforgery validation to succeed, we need to make sure that both the cookie token and the request token are included in requests that will go through the validation.

You will be relieved to hear that whenever you generate a form in a razor view using the new tag helpers, the request token is automatically included as a hidden field with the name __RequestVerificationToken (you can change it by setting a different name in the options when adding the Antiforgery services).

For example the following razor code:

<form asp-controller="Foo" asp-action="Bar">
    …
    <button type="submit">Submit</button>
</form>

Will generate the following html:

<form action="/Foo/Bar" method="post">
    …
    <button type="submit">Submit</button>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8P4n6uxULApNkzyVaa34lxdNGtmIOsdcJ7SYtZiwwTeX9DUiCWhGIndYmXAfTqW0U3sdSpzJ-NMEoQPjxXvx6-1V-5sAonTik5oN9Yd1hej6LmP1XcwnoiQJ2dRAMyhOMIYqbduDdRI1Uxqfd0GszvI">
</form>

You just need to make sure the form includes some of the asp-* tags, so it is interpreted by razor as a tag helper, and not just a regular form element.

  • If for whatever reasons you want to omit the hidden field from a form, you can do so by adding the attribute asp-antiforgery="false" to the form element.
  • If you use the html helpers in your razor views (as in @Html.BeginForm()), you can still manually generate the hidden input field using @Html.AntiForgeryToken().

So that’s how you generate a request token as a hidden field in the form, which will be then included within the posted data.

What about the cookie token?

Well, Antiforgery treats both the request and cookie tokens as a token set. When the IAntiforgery method GetAndStoreTokens(httpContext) is executed (which is what happens behind the scenes when generating the form hidden field), it returns the token set including both request and cookie tokens. And not only that, it will also make sure that:

  • The cookie token is added as an http only cookie to the current HttpContext response.
  • If the token set was already generated for this request (i.e. GetAndStoreTokens has already been called with the same httpContext), it will return the same token set instead of regenerating it again. This is important as it allows multiple elements of the page to get posted and also pass the validation, like having multiple forms (as the cookie would be the same for all forms, if every form had a different token, then only the form with the token matching the cookie one would pass the validation!).

Many of the cookie properties can be changed through the options:

  • The cookie is always set as an http only cookie (so JavaScript doesn’t have access to it)
  • The default cookie name is generated for each application as “.AspNetCore.AntiForgery.“ followed by a hash of the application name. It can be overridden by providing a CookieName in the options.
  • No cookie domain is set by default, so the browser assumes the request domain. You can specify one through the CookieDomain option.
  • The cookie path is defaulted from the current request path base (typically “/”), but can be forced with the CookiePath option.
  • You can also enable the flag RequireSsl in the options, which will set the Secure flag of the cookie as true.

As the browser will send the cookies with subsequent request, whenever the form is posted, the request will contain both the cookie token (in the cookie) and the request token (in the form field).

In short, as long as you somehow generate the request token, the cookie token will also be generated and automatically added to the response.

Including the tokens in AJAX requests

In the previous section, we have seen how to generate a hidden field with the request token inside forms. But what about when sending data as part of an AJAX request, without any server-side generated form involved?

Well, this depends a lot on what JavaScript framework you are using for structuring your client-side code. Angular provides CSRF support out of the box and is so commonly used these days that even the Antiforgery repo contains an example for it. I will too take a look at the Angular-Antiforgery integration and later I will explain how a similar approach could be manually introduced for simple jQuery requests.

CSRF – The Angular case

In the case of Angular, you will be using their $http service for sending AJAX requests. This service will automatically include a header with the name X-XSRF-TOKEN if it can find the token value as a cookie with the name XSRF-TOKEN. So the easiest way is to play the way Angular wants us to, and create some middleware that will get the request token, and store its value as the XSRF-TOKEN cookie.

Even if it is added as a cookie, this is still the request token and not the cookie token! It might sound confusing, so let me try to clarify it:

  • The application will send back to the browser a cookie XSRF-TOKEN with the request token and another cookie .AspNetCore.Antiforgery.* with the cookie token.
  • Whenever Angular sends an Ajax request, the request will include a header X-XSRF-TOKEN with the request token and the cookie .AspNetCore.Antiforgery.* with the cookie token.
  • The Antiforgery validation will make sure that both tokens are valid and share the same secret, etc.

Figure 3: CSRF tokens with Angular

Since the default header name for the request token is RequestVerificationToken, we need to change it and make sure Antiforgery searches for the request token in a header with name X-XSRF-TOKEN. Let’s just manually add Antiforgery and setup the options in the ConfigureServices method:

services.AddAntiforgery(opts => opts.HeaderName = "X-XSRF-Token");

Now we need to make sure we generate the tokens and include the request token in a cookie with name XSRF-TOKEN so Angular $http service can read it and include it as the header.

  • This cannot be an http only cookie, since Angular code needs to read the cookie value so it can be included as a header in subsequent requests!

We will be interested in doing so every time we generate a full html document, so we could create a new Result Filter that basically does this if the result is a ViewResult:

public class AngularAntiforgeryCookieResultFilter: ResultFilterAttribute
{
    private IAntiforgery antiforgery;
    public AngularAntiforgeryCookieResultFilter(IAntiforgery antiforgery)
    {
        this.antiforgery = antiforgery;
    }

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is ViewResult)
        {
            var tokens = antiforgery.GetAndStoreTokens(context.HttpContext);
            context.HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
        }
    }
}

The only remaining bit is to configure it as a global filter. This way every time we render a full html document, the response will also include cookies for both the cookie token and the request token. You will do so again in the ConfigureServices method:

services.AddAntiforgery(opts => opts.HeaderName = "X-XSRF-Token");
services.AddMvc(opts =>
{
    opts.Filters.AddService(typeof(AngularAntiforgeryCookieResultFilter));
});
services.AddTransient< AngularAntiforgeryCookieResultFilter >();

And that’s it, now your Angular code can use the $http service and the tokens will be included within the request. You can check an example with a simple TODO Angular application in GitHub.

CSRF – The manual case with jQuery

If you are using a framework other than Angular (or no framework at all), the way tokens are handled might be different. However the underlying principles in every case will be the same, as you always need to make sure that:

  • The tokens are generated server side.
  • The request token is made available to the client JavaScript code.
  • The client JavaScript code includes the request token either as a header or as a form field.

So let’s say your client code sends AJAX requests using jQuery. Since we have already created a Result Filter that includes the request token as a XSRF-TOKEN cookie, and have configured Antiforgery to look for the request token in a header named X-XSRF-TOKEN, we can reuse the same approach.

You will need to get the request token from the cookie and include it within your requests (be careful if you use something like $.ajaxSetup() as the token would be included on any requests, including those from 3rd party code using jQuery):

var token = readCookie('XSRF-TOKEN');
$.ajax({
    url: '/api/todos',
    method: 'PUT',
    data: JSON.stringify(todo),
    contentType: 'application/json',
    headers: { 'X-XSRF-TOKEN': token },
    success: onSuccess
});

Where readCookie can be something like the jQuery cookies plugin or just your own utility for reading the value of a cookie (taken from Stack Overflow):

function readCookie(name) {
    name += '=';
    for (var ca = document.cookie.split(/;\s*/), i = ca.length - 1; i >= 0; i--)
        if (!ca[i].indexOf(name))
            return ca[i].replace(name, '');
}

But we are just using those cookie and header names because we set the server this way for Angular before. If you are not using Angular, you could use whatever name you like for the cookie with the request token (as long as the middleware adding that cookie uses the same name) and the default header name (as long as you don’t specify a different one in the options):

var token = readCookie('AnyNameYouWant');
$.ajax({
    …
    headers: { 'RequestVerificationToken': token },
    …
});

In fact, you don’t necessarily need to use a cookie to propagate the request token to your JavaScript code. As long as you are able to do so, and the token is included within your AJAX requests, then the validation will work. For example, you could also render an inline script in your razor layout that adds the request token to some variable, which is later used by your JavaScript code executing jQuery AJAX requests:

@*In your layout*@
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery antiforgery;
@{ 
    var antiforgeryRequestToken = antiforgery.GetAndStoreTokens(Context).RequestToken;
}

    //Render the token in a property readable from your client JavaScript
    app.antiforgeryToken = @Json.Serialize(antiforgeryRequestToken);

//In your client JavaScript
$.ajax({
    …
    headers: { 'RequestVerificationToken': app.antiforgeryToken },
    …
});

Validate the request origin

You might have noticed that OWASP recommended another protection measure, validating the request origin. The way they recommend validating it is by:

1. Get the request origin (by looking at the Origin and Referer headers)

2. Get the target origin (looking at the Host and X-Forwarded-Host headers)

3. Validate that either the request and target origins are the same, or the request origin is included in a whitelisted list of additional origins.

You can implement an IAuthorizeFilter that goes through those steps for all unsafe requests (any request with a method other than GET, HEAD, TRACE and OPTIONS) and when the validation fails, sets the result as a 400:

context.Result = new BadRequestResult();

It shouldn’t be too hard writing such a filter and including it as a global filter. If you want to see an example including options for the whitelisted extra origins, check the sample project in GitHub.

Conclusion

Security is a critical aspect for any non-trivial application. Knowing the different types of attacks and how to protect against them, is an art in itself. Luckily this entire security process is simplified for us with mature frameworks that provide more and better security features.

When it comes to the particular CSRF attack, ASP.Net Core gives you the tools to protect your application but still requires some (minimum) effort to be properly configured and setup.

You can find a sample project with Antiforgery validations on GitHub.

Was this article worth reading? Share it with fellow developers too. Thanks!


TOP