-1

I have an OData controller that want to encode string fields of its output. OData output result is sent back to client as clear data but I want to encrypt them before sending it to client.

It seems that the best way is to use a customized OData serializer or a feed serializer to achieve my goal. But I'm not sure which class to customize. Is it better to override some methods or implement my own customized version of a serializing class.

Any help is appreciated.

Afshar Mohebi
  • 10,479
  • 17
  • 82
  • 126
  • Just use HTTPS, all data and the quarry string will be encrypted. If you do your own encryption how will you protect the key (keep it secret and share it between the client and server)? – zaph Nov 12 '16 at 12:58
  • HTTPS is not an option here. Client must not be able to see data. A process on client will decrypt data. I agree that key will be in client executables and could be find. But application is used in very few places that are supposed to have hack skills. – Afshar Mohebi Nov 12 '16 at 13:19
  • How about storing the "Encrypted" version of your data in the OData property, instead of messing with serializers? – Marvin Smit Nov 14 '16 at 09:15
  • @MarvinSmit How do this? Didn't understand your solution, sorry. – Afshar Mohebi Nov 14 '16 at 09:18
  • Create 2 propeties on your entity. 1 OData exposed, 1 internal. Internal one holds the unencrypted data. OData one uses "return Encrypt(internal):" on get and "internal = Decrypt(value)" on set, or something similar. – Marvin Smit Nov 14 '16 at 09:20

1 Answers1

0

Find a way to do it. I did it by customizing serializer by help of this guide. Final code:

using Microsoft.Data.Edm;
using Microsoft.Data.OData;
using System.Web.Http.OData.Formatter.Serialization;

namespace MyProj
{
    public class CustomODataEntityTypeSerializer : ODataEntityTypeSerializer
    {
        public CustomODataEntityTypeSerializer(ODataSerializerProvider serializerProvider) : base(serializerProvider)
        {
        }

        public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
        {
            //http://odata.github.io/WebApi/#06-03-costomize-odata-formatter

            if (graph is CompanyDto)
            {
                var company = (CompanyDto)graph;

                company.FirstName = Encrypt(company.FirstName);
                company.LastName = Encrypt(company.LastName);
            }

            base.WriteObjectInline(graph, expectedType, writer, writeContext);
        }
    }
}

And this class:

using Microsoft.Data.Edm;
using System.Web.Http.OData.Formatter.Serialization;

namespace MyProj
{
    public class CustomDefaultODataSerializerProvider : DefaultODataSerializerProvider
    {
        CustomODataEntityTypeSerializer _customODataEntityTypeSerializer;

        public CustomDefaultODataSerializerProvider()
        {
            _customODataEntityTypeSerializer = new CustomODataEntityTypeSerializer(this);
        }

        public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType.IsEntity())
            {
                return _customODataEntityTypeSerializer;
            }

            return base.GetEdmTypeSerializer(edmType);
        }
    }
}

And initializing it as follow:

            var odataFormatters = ODataMediaTypeFormatters.Create(new CustomDefaultODataSerializerProvider(), new DefaultODataDeserializerProvider());
        config.Formatters.InsertRange(0, odataFormatters);
Afshar Mohebi
  • 10,479
  • 17
  • 82
  • 126