How I can load a service dependency based on the route parameter?
My requirement is different, but I'll try to use a simple example.
A user can select the shipping provider (UPS, Fedex...) and the information is as part of the request model or route. Based on the route, I need to load the service class.
How it can be done in Autofac OWIN? Help on this will be appreciated
When you use the Autofac's OWIN integration, each request creates a new lifetime scope in which the current IOwinContext is registered, as you can see here.
You could then delegate the creation of your service to a factory that would take a dependency on IOwinContext.
public class MyServiceFactory
{
private readonly IOwinContext _context;
public MyServiceFactory(IOwinContext context)
{
_context = context;
}
public IService Create()
{
// inspect the context and determine which service you need
// you could return, dependending on, let's say, the URL
// - UpsService()
// - FedexService()
}
}
One thing you'll need to make sure is that you register your factory as InstancePerLifetimeScope since the IOwinContext will be different for each request.
Do you need to work at the OWIN layer, though? It will make things harder, and possibly a bit hacky, since OWIN is really just the HTTP layer, so there's no such thing as route data.
If you use ASP.NET Web API, you could base the factory on the current HttpRequestMessage if you use the RegisterHttpRequestMessage extension method.
You can then access route data through request.GetRequestContext().RouteData. Note that GetRequestContext is an extension method in the System.Net.Http namespace.
If you use ASP.NET MVC, you can register the AutofacWebTypesModule in the container, itself registering quite a few types in the container.
One of those is HttpRequestContext which has a RouteData property, so you can inject this one in the factory and apply your logic.
Related
I'm trying to create a flutter app using flutter_bloc, firebase auth and firestore.
I following flutter_firebase_login example which is truly amazing for all the testing coverage.
I would like to go one step further. Once the use is authenticated, I want to load the user profile from firestore, then actually display the app. (In practice, once the profile is loaded, I will have to do new firestore lookups that will depend on the profile info).
So I kind of have a chain of events:
Authenticate -> Load profile for user "uid" -> Load data depending on profile.
I'm wondering what is the good way to do that which still allows me to test my full app using mocks only.
The example injects the authenticationRepository into the App class then we can inject it in the test. My problem now is that, once the user is logged in and we redirect to the HomePage widget, this widget will have to create a new provider. But if it does create a new one, then I can't inject it anymore.
What is the good practice there? Here are the few options I've been considering:
Inject all the providers in the main()
I guess this would be the simplest solution. Though since those providers are kind of chained, I would have to pass the context data to every call on the "sub" providers, the context from the previous one. For instance:
ProfileRepository {
... getProfile(uid);
}
DataRepository {
... getData(... profile)
}
Dynamically build the providers
Ideally, I would like to not need those extra params in my providers and instead build my providers with those context values. Example:
ProfileRepository {
ProfileRepository(uid)...
... getProfile();
}
DataRepository {
DataRepository(profile)...
... getData()
}
So each time the uid changes, we would create a new provider for the profile and for each profile change we would create a new data provider.
This will simplify the calls in my app to not have to load the profile to get the data. The sub widgets just need to get the current provider and call the functions without the depending contexts.
Though just calling the constructor from my widgets would create problems for the tests DI which means I would have to create provider factories that I could then inject. And from the tests I would pass mock factories and in my main(), the prod factories.
Adding a state to my providers
I would inject all my factories in the main but instead of constructing them using the uid or the profile. Pseudo code:
ProfileRepository {
setUid(uid)...
... getProfile();
}
DataRepository {
setProfile(profile)...
... getData(... otherParams)
}
Each time the user changes or the profile changes, I just call the setters. That way I don't need to pass provider factories from the main.
Note
I considered to wrap the AuthenticationRepository into a UserProfileRepository which would remove one step here but for the data, this would not work.
I'm not sure what is the good practice here and would love to get feedback.
Thank you in advance!
I have an application where I'm registering a user so user will enter his data on JSP page and the data will be save into DB, the flow will be JSP->dispatcher->controller->Service->Dao.
Now in MemberController which is delegating the request to the Service, has a method register() which will take the MemberDto as a parameter now and return the Successfull msg to the success.jsp page. Sometihng like user registered successfully.
public String Register(MemberDto memberDto)
Now I want to expose this same method as RestFul service using Jersey for partners and also use this same method within my application as a normal MVC flow. How can I acheive this
So u want to use Jersey so import the jersey library to support JAX-RS.
#Path("/classlevelpath")
public class MyController {
#POST
#Produces(MediaType.APPLICATION-XML)
#Path("/register")
public String Register(MemberDto memberDto) {
}
}
Be careful JAX-RS (Jersey is an implementaion) and Spring REST annotations are different.
Annotate your rest class with #RestController. The best practice is to create another controller. By you can see this answer if you want to transform your existing controller: https://stackoverflow.com/questions/33062509/returning-view-from-spring-mvc-restcontroller
I am implementing custom external identity provider and to do this I need to implement ExternalIdentityProvider class from jackrabbit.
http://jackrabbit.apache.org/oak/docs/security/authentication/externalloginmodule.html
In normal case you would need to pass j_username and j_password and you can get these from values SimpleCredentials object
My question is that since I need to pass additional form parameter say for instance linkedin ID in my case, how do I achieve that?
#Component(
policy = ConfigurationPolicy.REQUIRE
)
#Service
public class RDBMSIdentityProvider implements ExternalIdentityProvider {
#Override
public ExternalUser authenticate(Credentials credentials)
throws ExternalIdentityException, LoginException {
//i can get username / password from credentials object
//how to get additional parameters from http request object?
}
Any input is highly appreciated.
Thanks!
The correct way to handle this is to have a custom AuthenticationHandler which creates an instance of a specific Credentials object with whatever parameters you need in it.
That said, if you are integrating with LinkedIn (and this is in AEM), you would be better served by integrating with the existing OAuth AuthenticationHandler. There is OOTB support for Facebook and Twitter, but the OAuth provider is designed to be pluggable for different OAuth Service Providers.
I have REST api for accessing "parties" and the URL's look like this:
/parties
/parties/{partyId}
Using Spring controllers and #PathVariable I'm able to implement this interface. But to prevent users from accessing parties they don't have access to, I have to add checks to every method call which is kind of repeating myself and I might forget to add it everywhere:
#RequestMapping(value="/parties/{partyId}", method=RequestMethod.GET)
public #ResponseBody Party getParty(#PathVariable Integer partyId){
authorizeForParty(partyId);
...
Now what I would like to do is create a check that would be called every time that user enters url like this:
/parties/{partyId}/**
How would I do something like this? Do I have to create some servlet filter and parse the url myself? If I have to parse the url then is there atleast tools that would make it easy? I wish there was a way to add a method to controller that would be called before methods but could still use #PathVariables and such...
What I ended up with is using the Spring MVC interceptors and parsing the path variables in the same way that Spring does. So I define an interceptor for the REST url:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/parties/*/**" />
<bean class="PartyAuthorizationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
The PartyAuthorizationInterceptor has to implement HandlerInterceptor in which we have to implement preHandle. It has HttpServletRequest as a parameter so we can get the request URL but we still have to parse the partyId from the url. After reading how Spring MVC does it, I found out they have a class named org.springframework.util.AntPathMatcher. It can read the path variables from the URL and place the values in a map. The method is called extractUriTemplateVariables.
So the result looks like this:
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String partyIdStr = new AntPathMatcher().extractUriTemplateVariables("/parties/{partyId}/**", request.getPathInfo()).get("partyId");
...
That makes the parsing almost as easy as using #PathVariable in MVC Controller methods. You still have to do conversions yourself(e.g. String -> Integer).
Now I can implement authorization logic on all urls that access a party in this interceptor and keep that logic out of the individual controller methods. Not as easy as I would have hoped but it gets the job done.
Are you already using some kind of security library in your application, e. g. Spring Security?
Because the kind of logic you want to implement is a classic case for an AccessDecisionVoter in an authentication chain. You would just put your API behind Spring Security's protection and implement the custom check as part of the security chain.
If you are not using a security framework at all, your idea of implementing a HandlerInterceptor may be the best alternative, though. But it would require you (as you mentioned) to take into account all kinds of obfuscation the user may use in order to gain access to other URLs (e. g. %-encoding of letters, ../../ patterns etc.).
I extended the Zend Frontcontroller with a personal one and also extended the frontcontroller application resource to use my personal front controller. All it basically does for the moment is assign the front variable within the application resource method getFrontController to my personal front controller. Lastly, I added the pluginpaths variable within application.ini to use my personal Application Resources. In any case, I'm getting the Zend Frontcontroller returned to me instead of my personal one. Anybody know why my personal application frontcontroller resource
isnt being used?
`
Since Zend_Controller_Front is a singleton, you will also need to override the getInstance() method to ensure it creates an instance of your class instead of the base class. You can just cut and paste the method to do this:
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}