Spring Security 6 Config for non authenticated Endpoints not working - spring

After updating Spring Boot to version 3.0.1 and Spring Security 6.0 the public endpoints without authentication are no longer working.
I'm followed the upgrade guide for Spring Security 6 and removed the WebSecurityConfigurerAdapter.
My Security Config:
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig {
#Value("${auth0.audience}")
private String audience;
#Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
private String issuer;
#Bean
JwtDecoder jwtDecoder() {
NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
JwtDecoders.fromOidcIssuerLocation(issuer);
OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(audience);
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuer);
OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);
jwtDecoder.setJwtValidator(withAudience);
return jwtDecoder;
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/rest/public/**").permitAll()
.anyRequest().authenticated()
)
.sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
.build();
}
}
I'm using Postman to execute GET-Calls (eg. http://localhost:8090/rest/public/export/) to my application and it keeps telling me that authentication is need -> 401 Unauthenticated
Spring Security specific Startup Logs
swordEncoderAuthenticationManagerBuilder : No authenticationProviders and no parentAuthenticationManager defined. Returning null.
o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter#6acb45c1, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#294c44b7, org.springframework.security.web.context.SecurityContextHolderFilter#5dd23809, org.springframework.security.web.header.HeaderWriterFilter#13390a96, org.springframework.security.web.csrf.CsrfFilter#af9dd34, org.springframework.security.web.authentication.logout.LogoutFilter#3f80d8c, org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter#41bd6a0f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#60ab895f, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#78bd02c8, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#30bbe83, org.springframework.security.web.access.ExceptionTranslationFilter#57b33c29, org.springframework.security.web.access.intercept.AuthorizationFilter#3c8fe8ad]
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path
Logs when calling an public endpoint:
o.s.security.web.FilterChainProxy : Securing GET /rest/public/export/
o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8090/rest/public/export/?continue to session
I've followed this guide: https://docs.spring.io/spring-security/reference/migration/index.html

You need to declare your class as #Configuration because otherwise the declared #Beans won't be created and registered in the application context. It should look like this:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig {

Related

How can I write intetgration tests Spring Web Client(Spring MVC) with Oauth2 when using Credentials Flow

I have an Oauth 2 client that actually interacts with another microservice that acts as an authorization server (auth-server).
I have an endpoint (use spring mvc). It has the annotation
#PreAuthorize("has Scope(T(.........).
#Configuration
public class AuthWebClientConfiguration {
#Bean
public OAuth2AuthorizedClientManager authorizedManager(
ClientRegistrationRepository client,
OAuth2AuthorizedClientRepository authorizedClient
) {
OAuth2AuthorizedClientProvider authorizedProvider =
OAuth2AuthorizedClientProviderBuilder
.builder()
.authorizationCode()
.refreshToken()
.clientCredentials()
.build();
DefaultOAuth2AuthorizedClientManager authorizedManager =
new DefaultOAuth2AuthorizedClientManager(
client,
authorizedClient
);
authorizedClientManager.setAuthorizedClientProvider(authorizedProvider);
return authorizedManager;
}
#Bean
public ServletOAuth2AuthorizedClientExchangeFilterFunction oauthClient(OAuth2AuthorizedClientManager authorizedManager) {
return new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedManager);
}
}
#Service
#RequiredArgsConstructor
public class AuthClientManager {
public static final String SERVICE_ID = "my-service";
private final OAuth2AuthorizedClientManager oAuth2Manager;
private final ServletOAuth2AuthorizedClientExchangeFilterFunction
filterFunction;
private final WebClient webClient;
private WebClient client;
public WebClient getClient() {
return Optional.ofNullable(client)
.orElseGet(() -> {
OAuth2AuthorizeRequest authorizeRequest =
OAuth2AuthorizeRequest.withClientRegistrationId(SERVICE_ID)
.principal(SERVICE_ID)
.build();
client = webClient
.mutate()
.filter(
(request, next) -> next
.exchange(
ClientRequest.from(request)
.attributes(
oauth2AuthorizedClient(
oAuth2Manager.authorize(authorizeRequest)
)
).build()
)
)
.apply(filterFunction.oauth2Configuration())
.build();
return client;
});
}
}
endpoint
#RequestMapping("email")
public interface RestController {
#PreAuthorize("hasScope(T(......MESSAGE_SEND)")
#PostMapping("v1/message")
ResponseEntity<Void> send(#Valid #RequestBody Dto dto);
}
implementation of endpoint
#RestController
#RequiredArgsConstructor
#Slf4j
public class RestControllerImpl implements RestController {
#Override
public ResponseEntity<Void> send(Dto dto) {
return new ResponseEntity<>(HttpStatus.OK);
}
}
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#Slf4j
#RequiredArgsConstructor
public class SecurityConfig extends GlobalMethodSecurityConfiguration {
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new ScopeAwareExpressionHandler();
}
#Bean
#Order(0)
SecurityFilterChain apiFilterChain(
HttpSecurity http,
#Value("${spring.security.oauth2.client.provider-uri}") String hostname
) throws Exception {
return http
.cors()
.configurationSource(request ->
new CorsConfiguration()
.applyPermitDefaultValues()
)
.and()
.csrf().disable()
.requestMatchers(
requestMatcherConfigurer -> requestMatcherConfigurer.antMatchers("/**")
)
.authorizeRequests(authorizeRequestsCustomized -> authorizeRequestsCustomized
.antMatchers(
"/swagger-ui/**"
)
.permitAll()
.anyRequest()
.authenticated()
)
.oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer ->
httpSecurityOAuth2ResourceServerConfigurer
.jwt()
.jwkSetUri(hostname + "/oauth2/jwks")
)
.build();
}
}
application.yaml
spring:
security:
oauth2:
client:
registration:
my-service: # my-service
provider: spring
client-id: 1
client-secret:1
authorization-grant-type: client_credentials
scope: message.send
client-name: 1
provider:
spring:
issuer-uri:locachost....
user-info-uri: locachost..../api/v1/users/me
user-name-attribute: id
A would like to write an integration test for this endpoint to verify that the Oauth2 client for Credentials flow is configured correctly. well, for one thing, the work of my endpoint.
How could I do that ?
I have not found any examples suitable for my task.
Could someone share knowledge about this case.
If you want to write integration test:
start authorization server
script query to get authorization token with WebClient or something
set test request Authorization header with bearer token you got.
I'd rather write unit tests with #WebmvcTest or #WebfluxTest bfluxTest and configure test security context with jwt() MockMvc post processor (or Word bTestClient mutator) from spring-security-test or #WithMockJwtAuth from https://github.com/ch4mpy/spring-addons

Problem calling a "bearer-only" keycloak endpoint from a springboot (client app) to a also spring boot (bearer only app)

Basically I'm trying to access a bearer-only endpoint from a client app which is using a "KeycloakRestTemplate".
I did follow this guidelines 1:1 (it is in German) : https://blog.codecentric.de/2017/09/keycloak-und-spring-security-teil-1-einrichtung-frontend/
My problem is that when I see the logs, the authentication on the side of the bearer only endpoint seems successful, as shown bellow:
Found [1] values in authorization header, selecting the first value for Bearer.
o.k.a.BearerTokenRequestAuthenticator : Verifying access_token
o.k.a.BearerTokenRequestAuthenticator : access_token: [LONG TOKEN HERE]
o.k.a.RefreshableKeycloakSecurityContext : checking whether to refresh.
org.keycloak.adapters.AdapterUtils : use realm role mappings
org.keycloak.adapters.AdapterUtils : Setting roles:
org.keycloak.adapters.AdapterUtils : role: create_vouchers
org.keycloak.adapters.AdapterUtils : role: public_realm_access
org.keycloak.adapters.AdapterUtils : role: overview_orders
org.keycloak.adapters.AdapterUtils : role: uma_authorization
User 'c1500da2-855f-4306-ab65-662160558101' invoking 'http://localhost:8082/articles' on client 'articlesBearerOnlyService'
o.k.adapters.RequestAuthenticator : Bearer AUTHENTICATED
.k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /articles
o.k.a.AuthenticatedActionsHandler : AuthenticatedActionsValve.invoke http://localhost:8082/articles
cors validation not needed as were not a secure session or origin header was null: {0}
o.k.a.AuthenticatedActionsHandler : Policy enforcement is disabled.
but then directly afterwards on the logs comes this:
o.k.adapters.PreAuthActionsHandler : adminRequest http://localhost:8082/login
o.k.adapters.PreAuthActionsHandler : checkCorsPreflight http://localhost:8082/login
.k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /login
o.k.a.AuthenticatedActionsHandler : AuthenticatedActionsValve.invoke http://localhost:8082/login
o.k.a.AuthenticatedActionsHandler : Origin: null uri: http://localhost:8082/login
o.k.a.AuthenticatedActionsHandler : cors validation not needed as were not a secure session or origin header was null: {0}
o.k.a.AuthenticatedActionsHandler : Policy enforcement is disabled.
so, it tries to redirect to adminRequest http://localhost:8082/login? why, and how could this be solved?
I did also also tried with postman (getting the acces-token from the token end-point) and pasting it on the Authorization header of this "bearer-only" endpoint, and similarly by seeing the logs, the user seems authorized exacltly like in the first log block above, the diference is that is doesn't try to redirect anywhere but I receive a 401.
{
"timestamp": "2019-09-05T11:18:51.347+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/articles" }
Could somebody please provide some guidance into a possible solution?
Thanks in advance!
----------------------------------------
EDITED
----------------------------------------
here is the application properties file:
server.port = 8082
spring.application.name = articleBearerOnlyService
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=[REALM]
keycloak.resource=articlesBearerOnlyService
keycloak.bearer-only=true
keycloak.cors=true
keycloak.credentials.secret=[SECRET]
keycloak.ssl-required = external
# access controlled through spring security
#keycloak.security-constraints[0].auth-roles[0]=overview_orders
#keycloak.security-constraints[0].security-collections[0].patterns[0]=/articles
logging.level.org.keycloak=TRACE
and here the SecurityConfig :
#KeycloakConfiguration
#EnableWebSecurity
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
private final KeycloakClientRequestFactory keycloakClientRequestFactory;
public SecurityConfig(KeycloakClientRequestFactory keycloakClientRequestFactory) {
this.keycloakClientRequestFactory = keycloakClientRequestFactory;
//to use principal and authentication together with #async
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
/* remove default spring "ROLE_" prefix appending to keycloak's roles*/
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
// NullAuthenticatedSessionStrategy() for bearer-only services
return new NullAuthenticatedSessionStrategy();
}
/* configure cors & requests handling behaviour*/
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.cors()
.and()
.csrf()
.disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and()
.authorizeRequests()
.antMatchers("/articles").hasRole("overview_orders")
.anyRequest().permitAll();
}
// Spring boot integration
#Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
// *************************** Avoid Bean redefinition ********************************
#Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
KeycloakAuthenticationProcessingFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
#Bean
public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
KeycloakPreAuthActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
#Bean
public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(
KeycloakAuthenticatedActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
#Bean
public FilterRegistrationBean keycloakSecurityContextRequestFilterBean(
KeycloakSecurityContextRequestFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(false);
return registrationBean;
}
#Bean
#Override
#ConditionalOnMissingBean(HttpSessionManager.class)
protected HttpSessionManager httpSessionManager() {
return new HttpSessionManager();
}
}
The #SpringBootApplication annotation is a composite of these three annotations: #EnableAutoConfiguration, #ComponentScan and #Configuration. Annotating a class e.g. com.example.demo.DemoApplication with #SpringBootApplication, results in Spring looking for other components, configurations, and services inside com.example.demo and all of its sub-packages.
A class like com.example.config.DemoConfig therefore cannot be found by Spring automatically. If you want, you can give hints to Spring where to look for components via #ComponentScan(basePackages = "com.some.package"). Check out this article if you like to know more.
In this particular case, my #KeycloakConfiguration class SecurityConfig{...}, was completely ignored, and thus the application behaved as if none security config was provided at all.
Now, why was the SecurityConfig ignored?
- it turned out to be (I almost feel shame) path location of the class; I usually would place such a class under:
com.[company].[domain].configuration
In my case (since I'm only prototyping with keycloak + spring and not particularly concerned with class location right now). I did place my SecurityConfig class under:
com.[company].configuration
This made spring boot completely ignore this class.
Follow up question: I'm new to Sprint boot, is it 100% necessary to place all code under "com.[company].[domain].configuration", without modifying the pom (just having a newly created vanilla springboot project via the initializr)?

CORS error for 192.168.0.3/v1 but not for 192.168.0.3/v1/signup

I am using Spring-boot config for basic-auth and when I am trying to access the http://192.168.0.3/v1 using credentials, I am getting CORS error, even though I have configurations for CORS.
The weird thing is, when I am accessing the http://192.168.0.3/v1/signup, I am able to create a user.
why CORS error for the root url access only?
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
#ComponentScan(basePackages = { "com.ofloy.rest.security" })
#Import({CorsConfig.class})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup/**").permitAll()
.anyRequest().authenticated()
.and().httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().csrf().disable()
;
}
}
#Configuration
public class CorsConfig {
#Bean
public FilterRegistrationBean<Filter> customCorsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<Filter>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
}
I am using UserDetailsService for querying the real user from my DB and set server.servlet.context-path = /v1/
Basically two issues I am facing with the above configuration:
I am able to access http://192.168.0.3/v1/signup but not
http://192.168.0.3/v1/ from the broweser, as getting CORS error.
Accessing http://192.168.0.3/v1(from POSTMAN) using the credentials to check if
the credentials are correct, give me the 404 error. 404 if
credentials are correct and 401 is not correct. Why 404?
Note: One thing I have noticed for second issues is, even if I send the POST request to http://192.168.0.3/v1, the spring Logs shows it GET request, here is the log stack.
DEBUG DispatcherServlet : GET "/v1/", parameters={}
WARN PageNotFound : No mapping for GET /v1/
DEBUG DispatcherServlet : Completed 404 NOT_FOUND
DEBUG DispatcherServlet : "ERROR" dispatch for GET "/v1/error", parameters={}
DEBUG RequestMappingHandlerMapping : Mapped to public
org.springframework.http.ResponseEntity org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
DEBUG HttpEntityMethodProcessor : Using 'application/json', given
[/] and supported [application/json, application/*+json]
DEBUG HttpEntityMethodProcessor : Writing [{timestamp=Wed Jan 30 16:16:40 IST 2019, status=404, error=Not Found, message=No message available,
path=/v1/}]
DEBUG DispatcherServlet : Exiting from "ERROR" dispatch, status 404
UPDATE: this is the CORS error in browser
Access to XMLHttpRequest at 'http://192.168.43.70:8085/v1' from
origin 'http://localhost:3007' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
Redirect is not allowed for a preflight request.
I would do something like below on the controller which handles the request:
#CrossOrigin(origins = "http://localhost:3007")
#RestController
#RequestMapping("/v1")
public class VoneController {

#preauthrize or #Secured is not working in Spring Oauth

#Preauthrize and #Secured annotations are not working in Spring Oauth (All examples I've referred to are for Spring basic security and not for Oauth protocol):
What I've done is:
I enabled global security in spring_security.xml
I used Preauthrize tag in service but it is not working.
Just add
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
To one of your configurations. I have added to my Resource Server Config
#Configuration
#EnableResourceServer
#Order(2)
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("Sample");
}
#Override
public void configure(HttpSecurity http) throws Exception {
//restrict access using #Secured or #PreAuthorize annotation
http.authorizeRequests().anyRequest().permitAll();
}
}
Worked flawlessly

How to configure Spring ACL without XML file

I am trying to add ACL capabilities to my server. I have configured spring security using java file and would like to add ACL in the same manner. How should I do it? All the tutorials I found used XML file.
SecurityInit:
#Order(1)
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
SecurityConfig
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled=true)
#Component
#ComponentScan(basePackages = {"test.package"})
public class SecurityConfig extends
WebSecurityConfigurerAdapter {
...
#Autowired
protected void registerAuthentication(UserDetailsService userDetailsService, AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
// http://stackoverflow.com/a/21100458/162345
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().disable()
.addFilterBefore(...)
.addFilterBefore(...)
// TODO: create a better way to differentiate login to signup
.exceptionHandling()
.authenticationEntryPoint(noRedirectForAnonymous)
.and()
.formLogin()
.successHandler(restAuthenticationSuccessHandler)
.failureHandler(restAuthenticationFailureHandler)
.and()
.logout()
.logoutSuccessHandler(noRedirectLogoutSuccessHandler)
.and()
.authorizeRequests()
.antMatchers("/api/keywords/**").permitAll()
.antMatchers("/api/**").authenticated();
}
}
You can configure spring acl with Java configuration class as follow
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ACLConfig extends GlobalMethodSecurityConfiguration {
#Autowired
DataSource dataSource;
EhCacheBasedAclCache aclCache() {
EhCacheFactoryBean factoryBean = new EhCacheFactoryBean();
EhCacheManagerFactoryBean cacheManager = new EhCacheManagerFactoryBean();
factoryBean.setName("aclCache");
factoryBean.setCacheManager(cacheManager.getObject());
return new EhCacheBasedAclCache(factoryBean.getObject());
}
LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger());
}
AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ACL_ADMIN"),
new SimpleGrantedAuthority("ROLE_ACL_ADMIN"),
new SimpleGrantedAuthority("ROLE_ACL_ADMIN"));
}
#Bean
JdbcMutableAclService aclService() {
JdbcMutableAclService service = new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
service.setClassIdentityQuery("select currval(pg_get_serial_sequence('acl_class', 'id'))");
service.setSidIdentityQuery("select currval(pg_get_serial_sequence('acl_sid', 'id'))");
return service;
}
#Bean
AclMasterService masterService() {
return new AclMasterService();
}
#Override
protected MethodSecurityExpressionHandler createExpressionHandler(){
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new AclPermissionEvaluator(aclService()));
return expressionHandler;
}
}
The important aspect of the configuration are extend from
GlobalMethodSecurityConfiguration
override the method
createExpressionHandler
and enable the Pre and Post anotations with the follow anotation at the begining of the class
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled =
true)
Now you can use anotations like
#PreAuthorize('hasPermission(#object,read)')
see the Contact sample of Spring Security or the spring security reference guide for more uses of #Pre and #Post anotations.
This configuration class was tested on Spring 4 , Spring Security 4.0.1 and Spring Security ACL 3.1.2. If you want configure the authentication you can use a different Java class or override the configure method from this. If you already have a configured ehcache this configuration could not work correctly due to the ehcache is a singleton class and this configuration try to create a new one.
There is no way to configure spring acl without xml file. This is mentioned in spring docs itself.Refer to spring documentation.

Resources