How to use PAX CDI with Declarative service - osgi

We are using CXF + DOSGI rest services
Interface:
#Path("/")
public interface DefaultApi{
#POST
#Path("/public/login")
#Consumes({ "application/json" })
#Produces({ "application/json" })
public Response login(#HeaderParam("User-Agent") String userAgent,#QueryParam("username") String username,#QueryParam("password") String password,
#Context UriInfo uriInfo,
#Context ResourceContext recourceContext);
Implementation:
#Component(immediate = true, configurationPolicy = ConfigurationPolicy.REQUIRE, configurationPid = "frontend.rest")
public class DefaultApiImpl implements DefaultApi {
Is it possible to use Apache Deltaspike for Method level Authorization along with CXF + DOSGI
https://deltaspike.apache.org/documentation/security.html
If possible how to do it ?
Is there any other alternative to do method level authorization with CXF + DOSGI

You can not mix deltaspike and declarative services. Deltaspike security is a cdi extension so you need to use pax cdi to expose your OSGi service.
Another thing is that you need to do the authentication in some way. I recommend to use the CXF JAASAuthenticationFeature. It can do basic auth against the configured jaas provider in karaf. The result is a jaas login that you probably can use in deltaspike security to base your authorization on.

Related

How to disable interceptor call for Actuators in Springboot application

I am trying to implement Prometheus in my microservices based spring boot application, deployed over weblogic server. As part of POC,I have included the configs as part of one war. To enable it, i have set below config -
Application.properties
management:
endpoint:
prometheus:
enabled: true
endpoints:
web:
exposure:
include: "*"
Gradle -
implementation 'io.micrometer:micrometer-registry-prometheus'
But the actuator request is getting blocked by existing interceptors. It asks to pass values in headers specific to our project. Through postman(http:localhost:8080/abc/actuator/prometheus), I am able to test my POC(with required headers) and it returns time-series data expected by Prometheus. But Prometheus is not able to scrap data on its own(with pull approach), as the call lacks headers in request.
I tried following links (link1,link2) to bypass it, but my request still got intercepted by existing interceptor.
Interceptors blocking the request are part of dependent jars.
Edited --
I have used following way to exclude all calls to interceptor -
#Configuration
public class MyConfig implements WebMvcConfigurer{
#Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("**/actuator/**");
}
}
MyCustomInterceptor
#Component
public class MyCustomInterceptor implements HandlerInterceptor{
}
I have not implemented anything custom in MyCustomInterceptor(as i only want to exclude all calls to 'actuator' endpoint from other interceptors).
#Configuration
public class ActuatorConfig extends WebMvcEndpointManagementContextConfiguration {
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebAnnotationEndpointDiscoverer endpointDiscoverer,
EndpointMediaTypes endpointMediaTypes,
CorsEndpointProperties corsProperties,
WebEndpointProperties webEndpointProperties) {
WebMvcEndpointHandlerMapping mapping = super.webEndpointServletHandlerMapping(
endpointDiscoverer,
endpointMediaTypes,
corsProperties,
webEndpointProperties);
mapping.setInterceptors(null);
return mapping;
}
}
Maybe you can override with setting null. I got code from https://github.com/spring-projects/spring-boot/issues/11234
AFAIK Spring HandlerInterceptor do not intercept actuator's endpoints by default.
Spring Boot can't intercept actuator access

Using gRPC communicate Spring Boot application together with consul or Eureka

How can we use grcp communication with spring boot application. And how we can use common service discovery method for use with grpc to get end point of spring boot application.
For service discovery, implement your own NameResolver.
I used below code to get instance discovery client. It help to call all servers using revers poxing.
#Autowired
private DiscoveryClient discoveryClient;
and below method help to call all the services using service name
#RequestMapping(method = RequestMethod.GET, value = "/senduser")
public ResponseEntity<?> sendMessageToAllServices() {
user u=null;
List<ServiceInstance> server=discoveryClient.getInstances("grpc-server");
for (ServiceInstance serviceInstance : server) {
String hostName=serviceInstance.getHost();
int gRpcPort=Integer.parseInt(serviceInstance.getMetadata().get("grpc.port"));
ManagedChannel channel=ManagedChannelBuilder.forAddress(hostName,gRpcPort).usePlaintext(true).build();
UserServiceBlockingStub stub=UserServiceGrpc.newBlockingStub(channel);
UserDetail user=UserDetail.newBuilder()
.setName("Thamira")
.setEmail("Thamira1005#gmail.com")
.setAge(24).setGender(Gender.Male)
.setPassword("password").build();
u=stub.createUser(user);
}
return ResponseEntity.ok("User "+u);
}
we can change register as a consul or eureka. This method support both of that.

How to expose both a SOAP web-service and RESTful API at the same time in Spring Boot?

In Spring Boot 1.4.3 I exposed a SOAP web service endpoint which works successfully on port 8080.
For the purpose of running a health check I also need to expose a RESTful API. I tried both using Actuator and a rest controller:
#RestController
public class RESTapis {
#RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, value = "/health")
public String healthCheck() {
return "ACK";
}
}
but in both cases I get the same response: HTTP 405 (method not allowed).
The REST api returns HTTP 200 if I disable the web-service.
How can I have both the SOAP web-service and REST working at the same time?
Here is the web-service configuration:
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/*");
}
}
So going off the messageDispatcherServlet method it looks like you are binding your servlet to all the incoming request due to the wildcard registration:
return new ServletRegistrationBean(servlet, "/*");
Hence the MessageDispatcher is intercepting all of your incoming requests and trying to find the /health and throwing http 405.
Fix:
return new ServletRegistrationBean(servlet, "/soap-api/*");
Explanation:
By binding the Message Dispatcher to a specific URI namespace we can ensure that all the request fired on the /soap-api/* namespace ONLY will be intercepted by the MessageDispatcher. And all the other requests will be intercepted by the DispatcherServlet making it possible to run a Rest interface in parallel to your Soap WS.
Suggestion:
Not knowing the reasons / specifics of the app, but going off the name of the method healthcheck(), you can look at using spring boot actuator to generate health checks, metrics for you app. You can also override it for customisations.
Reference for actuator: https://spring.io/guides/gs/actuator-service/

Using spring security annotations with keycloak

I'm just a beginner in Spring Security, but I would like to know is it possible to configure keycloak in a way that I can use #PreAuthorize, #PostAuthorize, #Secured and other annotations.
For example, I've configured the keycloak-spring-security-adapter and Spring Security in my simple Spring Rest webapp so that I have access to Principal object in my controller, like this:
#RestController
public class TMSRestController {
#RequestMapping("/greeting")
public Greeting greeting(Principal principal, #RequestParam(value="name") String name) {
return new Greeting(String.format(template, name));
}
...
}
But when I try this (just an example, actually I want to execute custom EL expression before authorization):
#RestController
public class TMSRestController {
#RequestMapping("/greeting")
#PreAuthorize("hasRole('ADMIN')")
public Greeting greeting(Principal principal, #RequestParam(value="name") String name) {
return new Greeting(String.format(template, name));
}
...
}
I get exception:
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
In my spring security config I enabled global method security:
What do I need to make this spring security annotations work? Is it possible to use this annotation in this context at all?
here is example code:
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
#ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class WebSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
}
and
#PreAuthorize("hasRole('ROLE_ADMIN')")
Apart from this code. you need to do the role mapping for realm roles and client(application roles). the application roles will be put in #PreAuthorize
You still have to configure Spring Security using Keycloak. Take a look at the adapter documentation for an annotation based configuration. Once that's set up your Spring Security annotations will work on authorized calls.

Spring RestTemplate as a Spring Service

I have developed a REST server with our app specific APIs. we also have deployed a different rest Job server into another location. Currently the way I am doing is .
#RestController
public class SparkJobController {
#Autowired
private IJobSchedulerService jobService;
...
And the Service Implementation is
#Service(value="jobService")
public class JobSchedulerServiceImpl implements IJobSchedulerService {
#Override
public Map triggerJob(String context) {
Map<String, ?> s = new HashMap<String,Object>();
RestTemplate restTemplate = new RestTemplate();
// restTemplate call to other REST API. and returns Map.
...
}
My question is , Is my approach correct ? Or Does Spring framework enables us to use some predefined APIs which can help to use RESTTemplate as a Service
[EDIT] : the deployed REST service is third party application.
I did some research and havent' seen yet a way to implement RestTemplate as a service.
I have seen RestTemplate defined in the bean config and auto wired in - https://www.informit.com/guides/content.aspx?g=java&seqNum=546
To summarize, most of the examples I have seen use Resttemplate, similar to how you have implemented in your code.

Resources