Ways of overriding the behavior of the lexik/jwt-authentication-bundle to allow n number of public keys from an external source - lexikjwtauthbundle

Some background:
We have many applications, each with their own auth provider and public / private keypairs and their own key rotation.
When a new application is spun up or rotates its keys the public key is persisted elsewhere in a key store for other applications to pick up.
I have a Symfony 5.4 service that I want to authenticate users from these applications, the JWT provided by them includes the KID in the header, so the flow would be:
Receive request with JWT
Get KID from header
Lookup KID in our key store and load the public key
Verify that the JWT signature matches.
From them on the flow is as you would expect, Load JWSUser etc and the firewall works the way it should do.
I could just grab the key store and generate a large config file for it, but that is less than ideal at runtime and looking through the code it tries every alternative key until one verifies successfully, and that does not scale.
As far as I can see I have two options:
Extend Lexik\Bundle\JWTAuthenticationBundle\Services\JWSProvider\LcobucciJWSProvider with my own and override the verify method to go and find the right public key first.
Create my own JWSProvider that implements JWSProviderInterface and reproduce most of the logic except for how it gets public keys for verification.
Obviously of those two, #1 looks most simple, however the LcobucciJWSProvider is marked #final in the docblock even though the final keyword is not in use in the class itself, so it probably shouldn't be extended.
Am I right in thinking those are my two options?
I was initially hoping I could just implement my own keyloader but it looks like they don't ever receive information about the requested key, just if the public or private key is wanted.

Related

Google compute project-wide SSH keys with jclouds

I'm trying to launch google compute instances from java code using jclouds. It's mostly working, however I'd like to use the project-wide SSH key I've defined instead of having jclouds generate a new user/key credential.
According to the README here - https://github.com/apache/jclouds/tree/master/providers/google-compute-engine:
For an instance to be ssable one of the following must happen: 1 - the project's metadata has an adequately built "sshKeys" entry and a corresponding private key is provided in GoogleComputeEngineTemplateOptions when createNodesInGroup is called. 2 - an instance of GoogleComputeEngineTemplateOptions with an adequate public and private key is provided.
I'm trying to do 1) above. I've correctly configured the project's metadata (I can use it to connect to manually-created instances that don't have jclouds-generated credentials), but I can't work out how to provide that key to GoogleComputeEngineTemplateOptions?
Neither
GoogleComputeEngineTemplateOptions.Builder.installPrivateKey(String key) or GoogleComputeEngineTemplateOptions.Builder.overrideLoginPrivateKey(String key) seem to work.
The documentation is pretty sparse - anyone know how to do it?
jclouds will create a key by default if you don't provide one. You could use the following to provide your auth private key and tell jclouds not to generate a new one:
TemplateOptions opts = computeService.templateOptions()
.as(GoogleComputeEngineTemplateOptions.class)
.overrideLoginPrivateKey(privateKey)
.autoCreateKeyPair(false);

Web API seems to be caching JsonFormatter with OData requests?

TL;DR: My OData requests seem to be hitting my custom JsonFormatter once and only once per OData GET method (per controller), which results in "stuck" (cached?) custom formatting.
I am working on a Web API project, and have implemented and registered my own JsonMediaTypeFormatter:
config.Formatters.Clear();
config.Formatters.Add(MyJsonFormatter);
'MyJsonFormatter' has custom implementations of the following:
`-> SerializerSettings
`-> ContractResolver
`-> CreateProperty
In my protected override CreateProperty(MemberInfo member, MemberSerialization memberSerialization) method, I restrict certain properties from being serialized based on user permissions.
This works great for all my API endpoints except for my OData enabled GET requests. Each controller has a GET method using the Primary Keys of the object, and an OData GET method which has a format similar to the following:
[HttpGet, Route]
public PageResult<Customer> GetOData(ODataQueryOptions<Customer> options)
{
IQueryable qCustomer = options.ApplyTo(_args.Context.Customers);
return new PageResult<Customer>(qCustomer as IEnumerable<Customer>, Request.GetNextPageLink(), Request.GetInlineCount());
}
If I put a breakpoint on my overwritten CreateProperty method, it gets hit with every API request. However, it will only get hit once per OData GET method per controller. So a subsequent call from a different user with different permissions skips my code and gives me the formatting used in the first call.
If I restart the API, I can again hit the breakpoint (once), and get my formatting permissions for the user the call was made by, but subsequent calls (no matter the user) do not hit my breakpoint. Obviously, restarting the API for every OData request is not a solution I can live with.
I have put almost a full day into researching this, and have found several posts (here, here, here, etc.) which lead me to believe I need to implement my own ODataMediaTypeFormatter.
However, if this is the case, why is it hitting my JsonFormatter breakpoint? It seems like it uses my formatter, somehow caches my format permissions for that controller, and uses them from then on.
(Secondly, creating my own ODataFormatter does not seem to be a valid option anymore, since the codebase has apparently changed since this post - CreateEdmTypeSerializer does not exist. (I'm using Microsoft ASP.NET Web API 2.1 OData, version 5.1.2).)
Question: Is there a way I can get OData to play nicely with my JsonFormatter, and run through my custom CreateProperty code for each request?
If someone can at minimum explain what is going on here, it may help to point me in the direction I need to go, but right now my brain is just melting. :P
Update: I published to IIS and found that if I recycle the app pool, the formatting seems to be refreshed. So it definitely seems that something is being cached, the question is 'what' and 'why' - do PageResults automatically get cached? How do I stop whatever is being cached from being cached?
I don't know that my question was asked very well, as at the time I didn't entirely know what I was looking for or what was going wrong... However, since then, I have found an answer and figured I would post in just in case someone else runs into my issue.
The issue I was having is that I need to not serialize specific properties in my webapi Json response based on the permissions of the caller. The problem was, the first call upon running the API worked fine, however subsequent calls were not hitting my breakpoints, and were being returned with the permissions of the first request.
The resolution I found was to override another method in my ContractResolver to disable caching for the types I didn't want cached (in this case, anything with Entity as its base class).
public class SecurityContractResolver : DefaultContractResolver
{
public override JsonContract ResolveContract(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
if (type.IsSubclassOf(typeof(Entity)))
return CreateContract(type); //don't use cache in base method - we need different contract resolution per user / permissions
return base.ResolveContract(type); // <-- the base class calls CreateContract and then caches the contract
}
.....
}
Seems to be working great so far. Hope this helps someone!

Using GET and POST vs getter and setter methods (URLS)

As a trained programmer, I have been taught, repeatedly to use getter and setter methods to control the access and modification of class variables. This is how you're told to do it in Java, Python, C++ and pretty much every other modern language under the sun. However, when I started learning about web development, this seemed cast aside. Instead, we're told to use one URL with GET and POST calls, which seems really odd.
So imagine I have a Person object and I want to update their age. In the non-HTTP world, you're supposed to have a method called <PersonObject>.getAge() and another method called <PersonObject>.setAge(int newAge). But say, instead, you've got a webserver that holds user profile information. According to HTTP conventions, you'd have a URL like '/account/age'. To get their age, you'd request that URL with a 'GET', and to set their age, you'd request that URL with a 'POST' and somehow (form, JSON, URL-arg, etc.) send the new value along.
The HTTP method just feels awkward. To me, that's analogous to changing the non-HTTP version to one method called age, and you'd get their age with <PersonObject>.age('GET'), and set their age with <PersonObject>.age(newAge, 'SET'). Why is it done that way?
Why not have one URL called '/account/getAge' and another called '/account/setAge'?
What you are refering to is a RESTful API. While not required (you could just use getters and setters) it is indeed considered good practice. This however does not meen you have to change the code of your data objects. I always use getters and setters for my business logic in the models layer.
What you are talking to through the HTTP request are the controllers however, and they rarely use getters and setters (I suppose I do not need to explain the MVC design pattern to an experienced programmer). You should never directly access your models through HTTP (how about authentication and error handling and stuff...)
If you have some spare time I would advise you to have a look at this screencast, which I found very useful.
You certainly could have separate URLs if you like, but getters and setters can share names in the original context of your question anyway because of overloading.
class Person {
private age;
public age() {
return this.age;
}
public age(int age) {
this.age = age;
}
}
So if it helps you, you can think of it like that.

Question on class implementation with interface

I have created the following classes for sharing images. They implement an interface, but I need a way of switching between them with user interaction. I've done it the following way:
As you can see, service 1 and service 2 implement iSharingServices, and inherit from PolimorphSharing.
PolimorphSharing is simply and an abstract class that implements the methods I want public from Service 1 and Service 2. Those methods will then be overridden on the Service 1 and Service 2.
Because I need a way to switch the service in runtime, I've created a gateway class that inherits from PolimorphSharing. I can then call it the following way:
private var sharingService:PolimorphSharing = new SharingServicesGW('svc1').createService();
This all works flawlessly, and I can now switch between services with no problem whatsoever. However, I feel there's something wrong about it, so I would like to ask you guys for some advice on how to better implement this.
Any opinions here would be appreciated. I feel like I'm kind of implementing the factory pattern here the hard way.
UPDATE:
Just adding some more insight to this. Basically the idea here is for my client to be able to upload images with various different public sharing services such as imageshack, imgur etc. I want my client to be able to select the service in which the image is to be published to (hence the "switching between them with user interaction" bit of the question.
The method that does the uploading bit, is requestShareImage(), processResults() simply turns whatever gets returned to a unique format, so my client can read off it always the same way. getObject() is my accessor, and onIOError will handle exceptions with any of the public API's
Thanks all in advance,
SharingServicesGW IS a factory. However, there's no need for it to - and it shouldn't - inherit from PolimorphSharing. Also you're doing it a bit skewed. The client should be using objects of the interface type, not the abstract type.
Your interface should be defining the public API, not your abstract base class. In fact in AS3 interfaces can only define public members, while pseudo abstract classes can enforce implementation of protected members.
-- EDIT --
here's a UML diagram of how I would do it

How to log user operations in a web application?

The environment of my application: web-based, Spring MVC+Security, Hibernate, MySQL(InnoDB)
I am working on a small database application operated from a web interface. There are specific and known users that handle the stored data. Now I need to keep track of every create/update/delete action a user executes on the database and produce simple, "list-like" reports from this. As of now, I am thinking of a "log" table (columns: userId + timestamp + description etc.). I guess an aspect could be fired upon any C(R)UD operation inserting a log row in this table. But I am not sure this is how it should be done.
I am also aware of the usual MySQL logs as well as log4j. As for the logfiles, I might need more information than what is available to MySQL. Log4j might be a solution, but I do not see how it is able to write to MySQL tables. Also, I would like to have some associations preserved in my log table (e.g. the user id) to let the db do the basic filtering etc. Directions on this one appreciated.
What would you recommend? Is there even any built-in support in Hibernate/Spring or is log4j the right way to go?
Thanks!
Log4j is modular, you can write your own backend that writes the log into a database if you wish to do so; in fact, it even comes with a JDBC appender right out of box, although make note of the big red warning there.
For Hibernate, you probably can build something on the interceptors and events that keep track of all modifications and log them to a special audit table.
Have you looked into using a MappedSuperclass for C(R)UD operation logging?
#MappedSuperclass
public class BaseEntity {
#Basic
#Temporal(TemporalType.TIMESTAMP)
public Date getLastUpdate() { ... }
public String getLastUpdater() { ... }
...
}
#Entity class Order extends BaseEntity {
#Id public Integer getId() { ... }
...
}
In case you go for logging solution and looking for doing it yourself, try searching for JDBCAppender, it's not perfect but should work.
In case you want off the shelf product for centralized logging - consider trying logFaces - it can write directly into your own database (Disclosure: I am the author of this product.)