Reputation: 123
I have a web service in my JHipster app which I need to call without an authentication:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/api/my_method_to_call_unauthenticated")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
}
}
Then in my Java code, I have a call to (Neo4j) DB:
@Override
public Optional<MyObject> find(String connectionId) {
return connectionRepository.find(connectionId);
}
Which fails with this stacktrace:
2020-11-16 14:04:36.637 ERROR 3348 --- [ XNIO-1 task-1] o.a.s.w.r.Resource : Exception in connectionSynced() with cause = 'NULL' and exception = 'Authentication object cannot be null'
java.lang.IllegalArgumentException: Authentication object cannot be null
at org.springframework.security.access.expression.SecurityExpressionRoot.<init>(SecurityExpressionRoot.java:60)
at org.springframework.security.data.repository.query.SecurityEvaluationContextExtension$1.<init>(SecurityEvaluationContextExtension.java:108)
at org.springframework.security.data.repository.query.SecurityEvaluationContextExtension.getRootObject(SecurityEvaluationContextExtension.java:108)
at org.springframework.data.spel.ExtensionAwareEvaluationContextProvider$EvaluationContextExtensionAdapter.<init>(ExtensionAwareEvaluationContextProvider.java:369)
at org.springframework.data.spel.ExtensionAwareEvaluationContextProvider.lambda$toAdapters$2(ExtensionAwareEvaluationContextProvider.java:159)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at org.springframework.data.spel.ExtensionAwareEvaluationContextProvider.toAdapters(ExtensionAwareEvaluationContextProvider.java:160)
at org.springframework.data.spel.ExtensionAwareEvaluationContextProvider.access$000(ExtensionAwareEvaluationContextProvider.java:65)
at org.springframework.data.spel.ExtensionAwareEvaluationContextProvider$ExtensionAwarePropertyAccessor.<init>(ExtensionAwareEvaluationContextProvider.java:182)
at org.springframework.data.spel.ExtensionAwareEvaluationContextProvider.getEvaluationContext(ExtensionAwareEvaluationContextProvider.java:110)
at org.springframework.data.repository.query.ExtensionAwareQueryMethodEvaluationContextProvider.getEvaluationContext(ExtensionAwareQueryMethodEvaluationContextProvider.java:89)
at org.springframework.data.repository.query.SpelEvaluator.evaluate(SpelEvaluator.java:59)
at org.neo4j.springframework.data.repository.query.StringBasedNeo4jQuery.bindParameters(StringBasedNeo4jQuery.java:163)
at org.neo4j.springframework.data.repository.query.StringBasedNeo4jQuery.prepareQuery(StringBasedNeo4jQuery.java:152)
at org.neo4j.springframework.data.repository.query.AbstractNeo4jQuery.execute(AbstractNeo4jQuery.java:69)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:618)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy184.findOwningPortfolio(Unknown Source)
at service.impl.ConnectionServiceImpl.find(ConnectionServiceImpl.java:85)
Here is my repository:
@Repository
public interface ConnectionRepository extends Neo4jRepository<UserConnection, String> {
@Query("MATCH (t:UserConnection { connection_id: $0 })-[:IN]-(p:Portfolio) RETURN p")
Optional<Portfolio> find(String connectionId);
}
Indeed, I need to be authenticated in my (Neo4j) repository but I would like not to, what am I missing?
Upvotes: 1
Views: 309
Reputation: 123
You're right Gaël, but the problem occurring right after this is the CSRF protection, which is unwanted here. So, I managed to have my unauthenticated web service work without CSRF with this:
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.ignoringAntMatchers("/api/my_method_to_call_unauthenticated") <<<
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
--- snip ---
.and()
.authorizeRequests()
.antMatchers("/api/my_method_to_call_unauthenticated").permitAll()
.antMatchers("/api/**").authenticated()
See here: Spring Boot
Upvotes: 1
Reputation: 16284
In SecurityConfiguration
, web.ignoring().antMatchers("/api/my_method_to_call_unauthenticated")
conflicts with .antMatchers("/api/**").authenticated()
due to URL overlapping
You should rather remove it and add a permitAll()
in right order:
.antMatchers("/api/my_method_to_call_unauthenticated").permitAll()
.antMatchers("/api/**").authenticated()
Upvotes: 0