I'm implementing an oAuth server and need to store refresh tokens, to do this I have (at the moment) chosen to serialize the tokens into JSON.
While I can see that the JSON includes everything that would be needed to rehydrate, when I de-serialize with token.FromJson() the embedded claims are not being reconstructed correctly.
So far I've considered inheriting from JsonConverter to create a claims converter but don't see a way of adjusting the global JsConfig to utilise it :(
Can any one point me in a good direction?
So...
Walking away from the code and returning did the trick!
Instead of using a JsonConverter you need to utilise a generic version of JsConfig when changing/overriding the behaviour of ServiceStack on a specific class, just stick the following in your services start-up code for example.
JsConfig<Claim>.SerializeFn = claim => string.Format("{0}|{1}", claim.Type, claim.Value);
JsConfig<Claim>.DeSerializeFn = claimDetails =>
{
var values = claimDetails.Split('|');
return new Claim(values[0], values[1]);
};
Related
Background
A data structure in my database consists of "sections"; lists of custom objects. The number of sections may expand in the future, so to keep my code as DRY as possible, I wanted to determine the section to add/update/delete an item from to be defined dynamically as a parameter.
I quickly realised that doing something like #Body() section: SectionA | SectionB | SectionC... disables validation so I needed a single DTO Section that could encompass all sections. To do that I need to define dynamically which validators to apply as I have several #IsNotEmpty constraints.
So I came across this post whose selected answer recommends the usage of groups.
This posed the following challenges:
I now have to write a custom validation pipe. Relied heavily on this
I want to override the global validator pipe that I already had running and use my custom one for just that method. Outcome: didn't work, had to start defining the pipe on every controller method, a tradeoff I am willing to accept. Looks like there is no simple alternative.
However, I'm now faced with the final problem: how to use the parameters in the request to define these groups in the validator; another brick wall. No simple solution.
Solution
This question has been asked here but no satisfactory solution was actually given.
Option one recommended redefining the scope of the pipe to "request" level but didn't explain how, and solutions found online didn't work.
The second solution, using a custom decorator to perform the validation instead, did work, very well in fact here is a simplified version of the code:
export const ProfileSectionData = createParamDecorator(
async (data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
let object = plainToInstance(SectionDto, request.body); // I don't need to access the metatype from the request because I know what type I need but I'm sure I could if need-be.
const groups = [request.params.profileSection];
let validatorOptions = { groups, ...defaultOptions };
const errors = await validate(object, validatorOptions);
if (errors.length > 0) {
throw new BadRequestException();
}
return request.body;
},
);
Implications?
Here's my question. When Jay McDoniel recommended using a custom decorator, they warn: "Do note, that this could impact how the ValidationPipe is functioning if that is bound globally, at the class, or method level."
What does this mean?
Are there any vulnerabilities or performance drawbacks associated with this solution?
Obviously, one drawback is that you are using validation outside a validation pipe which is not ideal from a point of view of order and single-responsibility but I can't think of tangible inconveniences beyond aesthetics and maintainability.
Knowing the background, would you have approached the problem in a completely different way?
When moving my functions to .net5 I faced the fact that POCO binding that worked fine with 3.1 is not applicable with .net 5 anymore for some reason. They say it will be implemented at some point maybe, but for the certain reasons I need it now. Tried to find some hacky way to implement this, but failed. The best thought I had was to implement explicit operator in my DTO object which will cast HttpRequestData to it's type, but the problem is that HttpRequestData is an abstract type, and it's concrete implementation type is internal. After that I tried to cast the input parameter to HttpRequestData in middleware with reflection, but parameters are stored in IReadOnlyDictionary which is immutable. So I ran out of ideas now. Maybe someone found workaround to this and can kindly share, would be much appreciated.
I suppose you're using the "dotnet-isolated" mode (only way to run on .NET 5).
I'm trying to find a more elegant solution to this as well.
Meanwhile, what I did was to deserialize the data myself, inside the function.
var body = await new StreamReader(request.Body).ReadToEndAsync();
var myobject = JsonSerializer.Deserialize<MyPocoClass>(json);
I would really prefer if the runtime did it by itself, but I couln't find a way yet. I read somewhere that it is possible to create our own binding code, but I haven't tried it.
I noticed that I could bind to individual properties of the json payload, but not to an object...
I hope this arrives in Azure Functions v4 + .NET6, since it is right around the corner.
I would like to add method such as view and json to the context object passed to my controllers. I do this in a middleware that runs before everything else:
async function(ctx, next){
ctx.view = view.bind(ctx);
ctx.json = json.bind(ctx);
await next()
ctx.renderer.render();
}
these methods set some conventional configuration object (Renderer) that the middleware interprets and then renders out the actual response by setting the correct ctx.body. That allows me to switch template language easily and have an easier time combining API and Template requests.
Except it doesn't work because after await next() the ctx.renderer is the default one, not the one set by controllers. I suspect it's a namespacing issue, but I am not sure where it comes from.
What's the best practice to attach functions to the context that can reference context without it being passed to them?
Ok it's here in the docs I just missed it, the docs are inside a repo and are not hosted, which makes them hard to navigate.
TL;DR: use app.context to access the context prototype. Adding functions there attaches them to the context object and allows you to use this from within to access it.
Trying to exclude properties from a model from being included during serialization.
I am using the following syntax:
JsConfig<MyTestClass>.ExcludePropertyNames = new[] { "ShortDescription" };
Just after that I have the following:
return (from o in __someProvider.GetAll() select (new
{
o.Name,
o.ShortDescription
o.InsertDate
}).TranslateTo<MyTestClass>()).ToList()
However once result is returned from the method, it still contains "ShortDescription" field in the Json. Am I doing something wrong?
JsConfig<T>.ExcludePropertyNames appears to be checked only once for each type, in a static constructor for TypeConfig<T>. Thus, if you are configuring ExcludePropertyNames in your service class, just before returning your response, it might be too late -- the TypeConfig properties may already be set up and cached for MyTestClass. I was able to reproduce this.
A more reliable alternative is to move all of your JsConfig<T> configuration to your AppHost setup code.
If you really do need to do this in your service class, e.g. if you are only conditionally excluding property names, then an alternative approach would be to ensure that JsConfig.IncludeNullValues is false (I believe it is by default) and in your service code set ShortDescription to null when appropriate.
When I enabled code contracts on my WPF control project I ran into a problem with an auto generated file which was created at compile time (XamlNamespace.GeneratedInternalTypeHelper). Note, the generated file is called GeneratedInternalTypeHelper.g.cs and is not the same as the GeneratedInternalTypeHelper.g.i.cs which there are several obsolete blog posts about.
I'm not exactly sure what its purpose is, but I am assuming it is important for some internal reflection to resolve XAML. The problem is that it does not have code contracts, nor is the code contract system smart enough to recognize it as an auto generated file. This leads to a bunch of errors from the static checker.
I tried searching for a solution to this problem, but it seems like nobody is developing WPF controls and using code contracts. I did come across an interesting attribute, ContractVerificationAttribute, which takes a boolean value to set whether the assembly or class is to be verified. This allows you to decorate a class as not verified. Sadly the GeneratedInternalTypeHelper is regenerated with every compile, so it is not possible to exclude just this one class. The inverse scenario is possible though, decorate the assembly as not verified and then opt in for every class.
To mitigate the obvious hack I wanted to create a test that would at least verify that the exposed classes have code contract verification with a test like the following to ensure that own classes were at least being verified:
[Fact]
public void AllAssemblyTypesAreDecoratedWithContractVerificationTrue()
{
var assembly = typeof(someType).Assembly;
var exposedTypes = assembly.GetTypes().Where(t=>!string.IsNullOrWhiteSpace(t.Namespace) && t.Namespace.StartsWith("MyNamespace") && !t.Name.StartsWith("<>"));
var areAnyNotContractVerified = exposedTypes.Any(t =>
{
var verificationAttribute = t.GetCustomAttributes(typeof(ContractVerificationAttribute), true).OfType<ContractVerificationAttribute>();
return verificationAttribute.Any() && verificationAttribute.First().Value;
});
Assert.False(areAnyNotContractVerified);
}
As you can see it takes all classes in the controls assembly and finds the one from the company namespace which are not also auto generated anonymous types (<>WeirdClassName).
(I also need to exclude Resources and settings, but I hope you get the idea).
I'm not loving the solution since there are ways of avoiding contract verification, but currently it's the best I can come up with. If anyone has a better solution, please let me know.
So you can treat this class exactly like you would treat any other "3rd party" class or library. I'm sure certain assumptions would hold with the interaction with this generated class so at the interaction points, decorate your own code with Contract.Assume(result != null) or similar.
var result = new GennedClass().GetSomeValue();
Contract.Assume(result != null);
What this does is translate into an assertion that is checked at run time, but it allows the static analyzer to reason about the rest of the code that you do control.