Custom Spring Condition causes java.lang.NoSuchMethodException: <init>() exception - spring

I'm just trying to override the default behaviour of WebSecurityConfiguration and had to write my own conditions to initiate the beans based on the properties defined.
I have defined no arg constructor inside my custom condition class. Irrespective of that, I get java.lang.NoSuchMethodException, when I spin up the app.
This is how my code looks:
#Configuration
#ConditionalOnClass(WebSecurityConfigurerAdapter.class)
#Slf4j
public class WebSecurityConfiguration {
class DefaultSecurityCondition implements Condition {
public DefaultSecurityCondition(){}
#Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (context.getEnvironment().getProperty("property.server.authorised-clients") == null &&
context.getEnvironment().getProperty("property.server.authorised-thumbprints") == null) {
return true;
}
return false;
}
}
#Configuration
#Conditional(DefaultSecurityCondition.class)
#EnableWebSecurity
public class DefaultAuthorisationConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/").permitAll()
.and().httpBasic().disable().authorizeRequests()
.and().csrf().disable();
}
}
}
However, when I try to start my app, I get below exception.
java.lang.NoSuchMethodException:
com.test.WebSecurityConfiguration$DefaultSecurityCondition.()
What am I doing wrong?

When it’s an inner class, DefaultSecurityCondition must be declared static. When it is not static an instance cannot be created without also having an instance of its outer class.

Related

Creating a global interceptor for all defined routes

I have multiple route builders within my project,
I want to define a single interceptSendToEndpoint that will affect all of the defined routes
For Example:
Public Route1 extends RouteBuilder {
public void configure() throws Exception {
from("direct:endpoint1").toD("http:\\someAddress1");
}
}
Public Route2 extends RouteBuilder {
public void configure() throws Exception {
from("direct:endpoint2").toD("http:\\someAddress2");
}
}
what I want to do here is to define a central interceptSendToEndpoint that will automatically capture all traffic sent to the camel HTTP component for all routes.
public class InterceptRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
interceptSendToEndpoint("http:*")
.process(exchange -> System.out.println("Hi from intercept"));
}
}
However due to how camel injects the intercept scope, I'm unable to do this easily,
Is there a way to tell the camel context that this intercept is for all defined routes within the context?
Note: I'm using camel 3.0.0
Camel team works for similar task in there (https://issues.apache.org/jira/projects/CAMEL/issues/CAMEL-16757?filter=allissues&orderby=cf%5B12310200%5D+ASC%2C+priority+DESC%2C+updated+DESC).
Create an abstract base class and define your in there and then extends it in main route
public abstract class BaseRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
interceptSendToEndpoint("http:*")
.process(exchange -> System.out.println("Hi from intercept"));
}
}
public class TaskRoute2 extends BaseRoute {
#Override
public void configure() throws Exception {
super.configure();
from("direct:endpoint2").toD("http:\\someAddress2");
}
}
public class TaskRoute2 extends BaseRoute {
#Override
public void configure() throws Exception {
super.configure();
from("direct:endpoint2").toD("http:\\someAddress2");
}
}

Problems using dbunit with Spring (without spring-test-dbunit)

I'm trying to use dbunit to test my DAOs. We use Spring in a version that is not compatible with spring-test-dbunit. I can't autowire my dao beans into my test class, because then I would have to use #RunWith(SpringJUnit4ClassRunner.class) which regards one parameterless constructor. My class looks like following:
public class DbUnitExample extends DBTestCase {
#Autowired
public MyDAO myDAO;
public DbUnitExample(String name) {
super(name);
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "com.mysql.jdbc.Driver");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "...");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "...");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "...");
}
#Override
protected IDataSet getDataSet() throws Exception {
return new FlatXmlDataSetBuilder().build(new FileInputStream("target/partial.xml"));
}
#Override
protected DatabaseOperation getSetUpOperation() throws Exception {
return DatabaseOperation.REFRESH;
}
#Override
protected DatabaseOperation getTearDownOperation() throws Exception {
return DatabaseOperation.NONE;
}
#Test
public void testSometing() throws Exception {
myDAO.deleteById(12662);
}
}
Of course I get an NPE because my dao bean can't be found. When I use #RunWith(SpringJUnit4ClassRunner.class) I need to provide one parameterless constructor and have to delete my "dbunit"-constructor. Is there a standard way or workaround to use dbunit with spring without the use of spring-test-dbunit
EDIT
My class now looks like following:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/test-application.xml")
#DirtiesContext
#TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class })
public class DbUnitExample extends DBTestCase {
#Autowired
public MyDAO myDAO;
public DbUnitExample() {
super("target/partial.xml");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "com.mysql.jdbc.Driver");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "...");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "...");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "...");
}
#Override
protected IDataSet getDataSet() throws Exception {
return new FlatXmlDataSetBuilder().build(new FileInputStream("target/partial.xml"));
}
#Override
protected DatabaseOperation getSetUpOperation() throws Exception {
return DatabaseOperation.REFRESH;
}
#Override
protected DatabaseOperation getTearDownOperation() throws Exception {
// return DatabaseOperation.NONE;
// return DatabaseOperation.REFRESH;
return DatabaseOperation.CLEAN_INSERT;
}
#Test
public void testSometing() throws Exception {
myDAO.deleteById(12662);
}
}
It compiles now, but has no dbunt-functionality, which means if I delete a row it doesn't get restored to it's previous state (inserted again).
Since you are using Spring, I suggest autowiring the dbUnit instances into the test. The dbUnit Test Cases page has "Configuration Example Using Spring" for the PrepAndExpectedTestCase, but just copy the code and change it to DBTestCase and adjust accordingly.

PreAuthorize not getting honored over ResourceServerConfigurerAdaptor

I have a Spring Resource Server with Spring Security enabled. In Resource Server, i am extending the ResourceServerConfigurerAdaptor, some like the following.
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.anonymous().disable().requestMatcher(new OAuthRequestedMatcher()).authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/admin/**").hasAnyRole("ADMIN")
.anyRequest().authenticated();
}
private static class OAuthRequestedMatcher implements RequestMatcher {
public boolean matches(HttpServletRequest request) {
String auth = request.getHeader("Authorization");
boolean haveOauth2Token = (auth != null) && auth.toLowerCase().startsWith("bearer");
boolean haveAccessToken = request.getParameter("access_token") != null;
return haveOauth2Token || haveAccessToken;
}
}
}
Here i am expecting /api/admin/** to be accessible to ADMIN Role only.
Everything works fine till now.
But now i am trying to override this behavior at the method level using #PreAuthorize method level annotation.
Following is the RestController
#RestController
#RequestMapping("/api/admin/event")
public class ShunyaEventResource {
#Autowired
private ShunyaEventService eventService;
#PreAuthorize("hasRole('ADMIN') or #oauth2.hasScope('write')")
#PostMapping
public void createEvent(#RequestBody ShunyaEvent event, Principal user) {
eventService.create(event);
}
}
So, i want to allow /api/admin/event to be accessible to #oauth2 write scope as well. But this does not work, unless either i remove /api/admin/** from antmatcher altogether or i add #oauth2.hasScope('write') in antmatcher itself.
I have already defined the below configuration
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
Here my question is why Method Level security not working for an endpoint that is already covered by ResourceServerConfigurerAdapter? What is precedence of security filter when same endpoint is covered by MethodLevel Security (using PreAuthorize) and HttpSecurity antMatcher?
Really appreciate any help on this.

Spring Boot #Conditional annotation gets ignored

I am trying to enable scheduler based on certain properties (Condition) however it ignores my #Conditional annotation irrespective condition outcome. Any suggestions?
Conditional Class
public class SchedulerCondition implements Condition {
#Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return property#1 || property#2
}
}
Configuration Class
#Configuration
public class Scheduler {
#Conditional(SchedulerCondition.class)
#Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
#Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public void processJobs() {
......
}
}

Run aspect on proxy object

I have following simple service:
#Service
public class TestServiceImpl implements TestService {
#Override
public void countExternal(Integer arg1) {
System.out.println("test - lock external");
count(arg1, new Integer(1));
}
public void count(Integer arg1, Integer arg2) {
System.out.println("test - lock internal");
}
}
that implements my simple interface:
public interface TestService {
void countExternal(Integer arg1);
}
Here's the aspect that I am using to do some validation etc. during count method:
#Aspect
#Component
public class TestAdvicer {
#Around("execution(* count(..))")
public Object advice(ProceedingJoinPoint joinPoint) throws Throwable {
// do som magic here
return joinPoint.proceed();
}
}
In my Spring configuration I have included autoproxying:
#EnableAspectJAutoProxy(proxyTargetClass = true)
Unfortunately, my TestAdvicer is never executed since count method is invoked from countExternal method. count method is executed on Proxy object and because of that advice didn't run.
Do you know how can I run my advice on Proxy object? What is the best way to solve this problem?

Resources