I have a Symfony 2.1 application where, depending on the url requested, I want to take a different action when the user's credentials have expired. I'm using the fos_userbundle which, by default, redirects to the login url. In my case, instead of redirecting, I want to return special response that the client will handle.
Idea #1:
I'm not sure exactly what I need to do to accomplish this. I've stepped through the code and found where the Symfony\Component\Security\Http\Firewall\ExceptionListener is catching the exception that was thrown and eventually a RedirectResponse is set. I think I need to hook into here somewhere and set a different response but I haven't found it yet.
Idea #2:
I think I maybe need to setup another firewall that will handle the missing credentials differently. This seems like it would be a lot more work and doesn't quite feel right.
Both of my ideas may be way off base. It seems like it shouldn't be that difficult of a think to figure out, but I've searched high and low and can't find an answer.
I dont know if they've changed the format for kernel listeners in 2.1 vs 2.0, but perhaps you could create a listener that handles the onKernelRequest method and checks to see if they are authenticated.
kernel.listener.pageloadlistener:
class: Acme\DemoBundle\EventListener\PageLoadListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
class PageLoadListener
{
public function onKernelRequest(GetResponseEvent $event)
{
//Do whatever here, you could pass in the security context in the construct of this class to get the user
}
}
Related
I'm pretty new to typescript and I faced the issue with extending the Request type. I actually found a solution, but it doesn't feel right to me, and seems like there might be a better way.
First, the structure. I have a middleware checkAuth that checks the Bearer token, finds the user in the database (or creates one, in case it's the first time) and adds user to the req variable.
Most people recommend modifying the Express' Request type with custom declarations. I don't like this idea, because that will put user object into all requests, even before I actually save user into req.
Another solution is what I use now:
interface ReqWithUser extends Request {
user?: {
...
}
}
This allows me to declare req: ReqWithUser. But there's a flaw. When I try to access req.user, typescript is telling me that it's possibly undefined. Well, that's exactly what I declared with user?:. If I don't put a question mark there, then typescript is mad in router, saying Property 'user' is missing in type Request. That's fair. One of the solution is to use req!.user. Solves all problems, but it still feels imperfect to me. I know the req.user is there, it's not optional, otherwise checkAuth would fail and return 401. If it didn't, the user is there. What feels like the right solution is somehow modify the req type after the checkAuth middleware. Because that's when user is added into the req. Is it possible?
The issue has nothing to do with your types, but it's the fact that Express will always emit Request and not RequestWithUser.
So in your middleware function, you will always get a Request. The only reason RequestWithUser is acceptable is because you made it optional.
Truth is the middleware / decorator pattern doesn't work that well with express. You have a few options (some of which you mentioned)
Use declaration merging to 'patch' the built-in Request. You already mentioned you don't like this though, because it's a bit of a hack.
Don't use Express' middleware system and instead write something that understands how types change with decorators. I don't know exactly what this looks like, or if this has been done before.
Whenever you want to use RequestWithUser in your controllers/middlewares start off with an assertion function to ensure that user exists (allowing you to make it non-optional).
Cast to RequestWithUser, when you need it.
All these options have drawbacks:
You don't like for the reasons mentioned. It's not always 'accurate' so you are sort of lying to Typescript for convenience.
Sounds hard to do
Requires the use of an assertion function, which means you need to do a little extra work every time you want to use the user property. This work is not needed because you as developer know.
You probably don't like casting for the same reason you don't like to use declaration merging.
By far I think 2 is the best solution, because it gives you the advantage of typing without any hacks and without having to do the extra work of an assertion function (which happens during runtime). But it means abandoning Express' Middleware system. I wouldn't know exactly how to write this code, but I am curious how if it can be done...
FYI I opened another stack overflow question, because I am curious:
Typescript typing for decorator middleware patterns
I am trying to build a custom Apollo extension to capture some performance metrics (duration of execution) of resolvers and logging them to an APM tool. From the Apollo documentation, Github issue here and an example published by Apollo, I found that the method willResolveField when overridden, receives GraphQLResolveInfo (which in turn has the parent type parentType and field name fieldName). If one can notice, the fields are already resolved when this method is called by the Apollo server. Does someone know where this field resolution actually takes place before sending it to willResolveField?
On the other note, unless my understanding is wrong - the name willResolveField seems to be quite misleading. Can someone kindly shed some light on this?
Sample code of what I'm trying to achieve
class GraphQLAPMExtension implements GraphQLExtension<TContext> {
requestDidStart(options:{ request, operationName, ... }) {
// perform APM specifics to log the request and other info
return (...errors) => {
if(errors.length) {
// some more custom APM stuff!
}
}
}
willResolveField(source, args, context: TContext, info: GraphQLResolveInfo) {
// info contains parentType and fieldName
// and it seems to be that fields are already resolved and passed to this function
}
}
After some amount of digging into the graphql package. It is looking like the function resolveFieldValueOrError does the resolution. It can be found under the ./execution section. Looks like I will have to fork the graphQl project and make the modifications that I wish.
Another, more practical direction, was to trace the Apollo server creation's tracing parameter. After some quick digging, found that it is using the apollo-engine-reporting package.
There is already an extension for tracing requests that's built into ApolloServer. The source code can be found here. It sounds like you could just fork that.
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]);
};
If I create my httpBuilder as shown below (assume that a proxyUsername IS set, so setCredentials is called), then calls to httpAddress-es that are passed in properly are routed through the proxy. However, the Application has some http calls that are within the local network. Can http.nonProxyHosts be used to work around this and bypass the Proxy? If so, how? Use System.setProperty? Or something on HttpBuilder?
HTTPBuilder httpBuilder = new HTTPBuilder(httpAddress)
httpBuilder.setProxy(webProxyHost, webProxyPort, webProxyProtocol)
if (proxyUsername) {
httpBuilder.client.getCredentialsProvider().setCredentials(
new AuthScope(webProxyHost, webProxyPort),
new UsernamePasswordCredentials(proxyUsername, proxyPassword))
}
}
In the code above, all of the various named elements (webProxyHost, etc) are declared as String and set accordingly.
In answer to the question in the above comment, our primary 'nonProxyHost' need was for 'localhost' which is there by default. Thus this ceased to be an issue. Did not ever really find out how to accomplish this as it is somewhat version-specific on HttpClient.
You can set the System property:
System.setProperty('http.nonProxyHosts', myNonProxyHosts)
However, if you call 'setProxy' on HttpBuilder, even if you call 'useSystemProperties' it will not. This is in their documentation, just not obvious!
Finally, you might be able to call:
httpBuilder.client.params.setParameter('http.nonProxyHosts', myNonProxyHosts)
But I do not know for sure if that is the property name and documentation of those properties is hard to find. Worse - those 'params' are deprecated - you are supposed to use the better 'config' classes, though once again finding comprehensive documentation on all the parameters for that is not the easiest! Wish I could have been of more help!
I have an action in Controller that is secured with #Check annotation.
#With(Secure.class)
public class Application extends Controller {
#Check("admin")
public static void securedMethod() {
//secured code
}
When I call this action from browser, it calls boolean check(String profile) from Security class. But when I call this action from another action:
Application.securedMethod();
it just calls secured code, omitting Security.check() call. I thought, #Check should not allow execution of securedMethod() unless Security.check() return true. Any ideas how can I make it behave like this?
The reason is the way the Secure controller works. The #Check annotation is only validated at the beginning of a request, via a method annotated with #Before. You can see how it's done in the sample code.
Usually it should not be a problem as you should not call a method with bigger restrictions from a method with less security restrictions (as it may lead to security issues). In your case you should validate the workflow you are using, as you may want to avoid that call.