I'm trying to migrate my xml servlet config to java config.
The below config is my servlet configuration, that enables custom security annotations on Controller layer.
<security:global-method-security pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler"/>
</security:global-method-security>
<bean id="expressionHandler" class="yyy.MyMethodSecurityExpressionHandler" />
I've also have a working spring security xml configuration, that is in order to be replaced by java config, but not now. Here some pieces of my security config:
<bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<constructor-arg>
<ref bean="authenticationProvider"/>
</constructor-arg>
</bean>
<security:authentication-manager>
<security:authentication-provider user-service-ref="userDetailsService" />
</security:authentication-manager>
<security:global-method-security pre-post-annotations="enabled" />
I want to start to migrate my servlet config enabling security @PreAuthorize
and @PostAuthorize
tag in Controller layer.
I've found this annotation: @EnableGlobalMethodSecurity(prePostEnabled=true)
, but putting it on my servlet config:
@Configuration
@ComponentScan(basePackages= {
"....."
})
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebappServletConfig extends WebMvcConfigurationSupport {
I get this exception:
java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found []
Moreover I don't know how to set my custom expression-handler!
someone with some tips? Thank you
Method-level security is implemented by placing the @PreAuthorize annotation on controller methods (actually one of a set of annotations available, but the most commonly used). This annotation contains a Spring Expression Language (SpEL) snippet that is assessed to determine if the request should be authenticated.
The global method security functionality is disabled by default. To enable it, you use the @EnableGlobalMethodSecurity annotation over the configuration class of your application. You can apply authorization rules that the application checks before the call to a method.
Update (after updated question)
It appears you are encountering SEC-2479. There are a few ways around this. The easiest of which is to use the result of @Autowired for the AuthenticationManager. To do this you must extend GlobalMethodSecurityConfiguration and override the authenticationManager method.
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
private AuthenticationManager am;
@Override
protected AuthenticationManager authenticationManager() {
return am;
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
// ... create and return custom MethodSecurityExpressionHandler ...
return expressionHander;
}
}
Original Answer
You need to configure some sort of Authentication. So you will need to have the following:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
If you are not using web based security, the reference provides an example of how to configure the method security expression handler.
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
// ... create and return custom MethodSecurityExpressionHandler ...
return expressionHander;
}
}
If you are only wanting a custom method expression handler to provide a permission evaluator, then you only need to create a PermissionEvaluator bean like this:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Bean
public PermissionEvaluator permissionEvaluator() {
// ... create and return custom PermissionEvaluator ...
return permissionEvaluator;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With