I am trying to port the code of an Angular 2 app to Angular Dart, so that I can reuse the business logic in Flutter.
My app makes use of HttpInterceptors for Error handling and server authorization.
In typescript I would inject a simple service :
#Injectable({
providedIn: 'root'
})
export class InterceptorService implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return;
}
constructor(private auth: AuthService) { }
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {}
}
But the Dart API does not seem to have an HttpInterceptor class. Does one have to extend the HttpClient class in order to do so ?
I have looked at this S.O question but it dates back from 5 years ago, the way to do it has probably changed quite a bit in the meantime.
Turns out there are a couple ways you can achieve this in Angular Dart / Flutter.
Some third party libraries built on top of dart http provide convenience methods for Http interception (DIO, Http Interceptor). However, both handle interception at the client level.
I decided to go with the Dart Http library, using the recommended method :
class UserAgentClient extends http.BaseClient {
final String userAgent;
final http.Client _inner;
UserAgentClient(this.userAgent, this._inner);
Future<StreamedResponse> send(BaseRequest request) {
request.headers['user-agent'] = userAgent;
return _inner.send(request);
}
}
Related
I am running two different Payara Micro microservices in one cluster.
The issue I have is that when I try to access the OpenAPI URL of MyApp1 like http://mylink.com/myApp1/openapi it does not work. It actually works when I use URL http://mylink.com/openapi.
This becomes an issue when I want to see the API for the other microservice like http://mylink.com/myApp2/openapi which does not work.
Is there a way in Payara Micro of telling OpenAPI to use the application's context in it's path just like all the other URL in the application do?
As you can see in my previous comment, I've also struggled with the same situation.
Context - openapi and microprofile
First let me say that having /openapi URL in the root is the intended behaviour of microprofile-open. Documentation always uses /openapi path as the right to get the document LINK
In the implementation, is very clear that this behaviour is both wanted as enforced:
In the ServletContainerInitializer for OpenApi one can see the following code
// Only deploy to app root
if (!"".equals(ctx.getContextPath())) {
return;
}
Workaround aka Solution.
Now that is clear that we cannot configured this, since it's intended behaviour, one solution ( the one I'm proposing ) is to proxy the request to /YOUR_APP/openapi to /openapi.
Since my application is a jax-rs one, deployed on openshift, and I don't want to have a dedicated proxy application for this, I've just created a simple Resource/Controller to proxy this specific request for me.
The outstanding method behind:
#GET
#Path("")
public Response proxyOpenApiCall(){
log.debug("proxyOpenApiCall called");
String entity = client.target("http://localhost:8080")
.path("openapi").request()
.get(String.class);
return Response.ok(entity).build();
}
I was able to fix this with a small forward proxy. Therefore I create a new REST enpoint wich is callable from public and returns the content of internal http endpoint.
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#RequestScoped
#ApplicationPath("/")
#Path("/")
public class OpenApiProxyRestFacade extends Application {
private Client client;
#PostConstruct
public void init() {
this.client = ClientBuilder.newClient();
}
#GET
#Path("/openapi")
#Produces(MediaType.APPLICATION_JSON)
public Response proxyOpenApiCall() {
String entity = client.target("http://localhost:9080").path("openapi").request().get(String.class);
return Response.ok(entity).build();
}
#GET
#Path("/openapi/ui")
#Produces(MediaType.APPLICATION_JSON)
public Response proxyOpenApiUiCall() {
String entity = client.target("http://localhost:9080/openapi").path("ui").request().get(String.class);
return Response.ok(entity).build();
}
#PreDestroy
public void destroy() {
this.client.close();
}
}
For openapi, you can set this property for change of url, so it is configurable after all
mp.openapi.extensions.path=/yourapi/whatever
and for the openapi-UI set this
openapi.ui.yamlUrl=/yourapi/whatever
Sources: I first googled for mp.openapi.xxx parameters, (I found them in source code) which led me to this url
https://download.eclipse.org/microprofile/microprofile-open-api-1.0/microprofile-openapi-spec.html
and after looking for more stuff there was one simple sentence mentioning that there is also mp.openapi.extensions and after googling those further I found this random doc here https://github.com/wildfly/wildfly/blob/main/docs/src/main/asciidoc/_admin-guide/subsystem-configuration/MicroProfile_OpenAPI.adoc
I am building an authorization service for my nestjs app.
For every protected resource on my app (Media, Game, ...), I have a *RoleEntity associated (MediaRoleEntity, GameRoleEntity, ...) that defines what a user can do with a specific resource. Each one of this *RoleEntity implements RoleEntityInterface:
export interface RoleEntityInterface<T extends ResourceEntity> {
resource: T;
user: UserEntity;
role: string;
}
Each protected entity (MediaEntity, GameEntity, ...) extends ResourceEntity.
Now I want to build a generic provider RoleService, responsible for database interaction:
#Injectable()
export class RoleService<T extends ResourceEntity> {
readonly roleRepository: Repository<RoleEntityInterface<T>>;
async read(roleDto: Partial<RoleDto<T>>): Promise<RoleEntityInterface<T>> {
return this.roleRepository.findOne({
where: { ...roleDto },
});
}
async create(roleDto: RoleDto<T> | RoleDto<T>[]): Promise<void> {
await this.roleRepository.insert(roleDto);
}
}
And I want inject this service in guards, interceptors...
Problem, I don't know how to do that, more precisely:
How can I dynamically inject the roleRepository ? (I imagine some kind of factory has to be involved.)
REAL USE CASE
I want to be able to protect resources with a guard:
#Injectable()
export class RoleGuard<T extends ResourceEntity> implements CanActivate {
constructor(
private authService: AuthService,
private roleService: RoleService<T>,
private readonly reflector: Reflector,
) {}
...
}
Now in a controller, when I use
#Role('Admin')
#UseGuards(RoleGuard<MediaEntity>)
Get()
...
It would be perfect if the whole thing magically works :), ie correct roleService with correct roleRepository are properly injected.
I am completely new to nestjs and typescript (and never played with angular neither) so maybe the whole approach is wrong..
I am trying to wire up a basic Angular2 app that uses the Http service. (Most of the tutorials I've seen do this by having a Component consume the Http service, which seems wrong unless the basic philosophy of thin controllers has changed – but that's a different question.)
I would like to create a service that uses Angular's Http service. But I can't figure out how to inject the Http service other than this:
boot.ts:
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';
import {HTTP_PROVIDERS } from 'angular2/http';
bootstrap(AppComponent, [HTTP_PROVIDERS]);
myService.ts:
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
#Injectable()
export class aService{
constructor(http:Http){
}
/** do some stuff *//
}
This works, but it seem very wrong to require the user of the service to know the service's dependencies and be required to inject them into the bootstrap process. It seems like there should be a way to directly hand a providers array to a service the same way you can a component, but I can't find it. Am I just missing something?
Update
This way if a parent injector provides an implementation for OtherService this one is used, otherwise OtherServiceImpl is used (default).
#Injectable()
class SomeService {
OtherService _other;
SomeService(Injector injector) {
_other = injector.getOptional(OtherService);
if (_other == null) {
_other = injector.resolveAndCreateChild([
provide(OtherService, useClass: OtherServiceImpl)
]).get(OtherService);
}
_other.doSomething();
}
}
If you provide another one like
bootstrap(AppElement, [
provide(OtherService, useClass: OtherServiceImpl2)
]);
OtherServiceImpl2 is used.
See also https://github.com/angular/angular/issues/5622
Original
You could just make the http service optional (using the #Optional() annotation) and if none is provided just create an instance inside the constructor with new Http().
This way the user doesn't need to know about the services dependencies, but is able to pass alternative implementations if necessary (for example for testing).
If creating the dependeny inside the service requires DI itself, you can inject an injector and use it to get dependencies.
See also optional dependencies in http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html
What also could work (not tried myself yet) is just to create a child injector and instruct it to skip self
From the SkipSelfMetadata documentation
class Dependency {
}
#Injectable()
class NeedsDependency {
dependency;
constructor(#SkipSelf() dependency:Dependency) {
this.dependency = dependency;
}
}
var parent = Injector.resolveAndCreate([Dependency]);
var child = parent.resolveAndCreateChild([NeedsDependency]);
expect(child.get(NeedsDependency).dependency instanceof Depedency).toBe(true);
var inj = Injector.resolveAndCreate([Dependency, NeedsDependency]);
expect(() => inj.get(NeedsDependency)).toThrowError();
I don't know yet if this still resolves from "self" if parent can't provide the requested type.
can I use Spring Security or Shiro Security with Ninja Framework or Spark Framework? I can't find any example to integrate this security frames with web frames. there is not any information in the ninja web site about user auth and web app security.
This question is quite old, but I am unable to find any example of integrating Apache Shiro with Ninja Framework, so here are my findings about this.
Ninja Framework requires an instance of AbstractModule, it shows me an error when you try something like the configuration that is recommended here:
package conf;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import org.apache.shiro.config.Ini;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.guice.ShiroModule;
class Module extends ShiroModule {
protected void configureShiro() {
try {
bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
} catch (NoSuchMethodException e) {
addError(e);
}
}
#Provides
Ini loadShiroIni() {
return Ini.fromResourcePath("classpath:shiro.ini");
}
}
However checking the source code of ShiroModule class I noticed that it extends PrivateModule so this should work, at least I get no compilation errors:
package conf;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import org.apache.shiro.config.Ini;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.guice.ShiroModule;
public class Module extends AbstractModule
{
#Override
protected void configure()
{
install(new ShiroModule()
{
#Override
protected void configureShiro()
{
//shiro recomended configuration
try {
bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
} catch (NoSuchMethodException e) {
addError(e);
}
}
#Provides
Ini loadShiroIni()
{
return Ini.fromResourcePath("classpath:shiro.ini");
}
});
}
}
Spark has the notion of filters. http://sparkjava.com/documentation.html#filters therefore you can add the Shiro or Spring Security filter. That said, it isn't as simple as dropping in a filter for either of these security frameworks. But in theory...
if you want to secure web restful api, suggest use the sureness - https://github.com/tomsun28/sureness
It is no specific framework dependency(support springboot, quarkus, javalin, ktor and more).
The essence of sureness is to intercept all rest requests for authenticating and Authorizing.
The interceptor can be a filter or a spring interceptor, it intercepts all request to check them.
What you need to know is that sureness is a project created by us, welcome to use.
I have a Java code using youtube-api to upload videos. Until now I was using the system configuration to set the proxy (http and https) and everything is working fine that way. But now I have a new requirement regarding the way we use proxy on the server. As we have other services running on the very same server, they asked me to not configure the proxy using system wide approach, because this affect all the services using JVM.
System.setProperty("http.proxyHost", httpProxyHost);
System.setProperty("http.proxyPort", httpProxyPort);
and
System.setProperty("https.proxyHost", httpsProxyHost);
System.setProperty("https.proxyPort", httpsProxyPort);
I have spent the last couple days researching that on the Internet and didn't find anything useful. I found a explanation on the C# API what seems to be setting the proxy to the connection and I didn't find a way to implement this same approach on Java.
I want to do something like this:
service = new YouTubeService(APPLICATION_NAME, DEVELOPER_KEY);
service.setUserCredentials(userName, password);
uploader = new ResumableGDataFileUploader.Builder(
service, new URL(RESUMABLE_UPLOAD_URL), ms, newVideoEntry)
.title(videoTitle)
.trackProgress(listener, PROGRESS_UPDATE_INTERVAL)
.chunkSize(DEFAULT_CHUNK_SIZE).build();
// fictional code to show what I want to do
uploader.setProxyHttp(httpProxyHost, httpProxyPort);
uploader.setProxyHttps(httpsProxyHost, httpsProxyPort);
uploader.start();
This is very similar to what Java already allow us to do. See this http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
I just resolved with the following code. Adapt the method setPersonalUrlConnectionFactory to set your proxy and call it passing as argument your uploader.
package com.google.gdata.client.uploader;
import com.google.gdata.client.media.ResumableGDataFileUploader;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PersonalUrlConnectionInjector {
public static void setPersonalUrlConnectionFactory(ResumableGDataFileUploader uploader) {
try {
java.lang.reflect.Field field = uploader.getClass().getSuperclass().getDeclaredField("urlConnectionFactory");
field.setAccessible(true);
java.lang.reflect.Field modifiersField = java.lang.reflect.Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
field.set(uploader, new UrlConnectionFactory() {
#Override
public HttpURLConnection create(URL url) throws IOException {
return new sun.net.www.protocol.http.HttpURLConnection(url, MY_PROXY);
}
});
} catch (Exception e) {
/* DO LOG */
}
}
}