I'm new to Spring, SpringSecurity and Boot - trying to create a webapplication where I have to lookup in a database whether a user has access to a requested URL or not. I've managed to make the authentication work (i.e UserDetailService with loadUserByUsername). In the database I have a table for Users, Groups, Roles and a last one for URLs containing the URLs and Config Attributes (typically equal to the Roles).
So I have this working configuration (by the way, I'm trying to configure everything in Java - not using XML):
@Resource(name="authService")
private UserDetailsService userDetailsService;
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
AuthenticationProvider customAuthenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/table/list").permitAll()
.and()
.logout()
.logoutUrl("/logout").permitAll()
.and()
.authorizeRequests()
.antMatchers(
"/home",
"/images/**",
"/bootstrap/**",
"/jquery-ui/**",
"/jquery-2.1.3.min.js",
"/error"
).permitAll()
.antMatchers("/user/list").permitAll()
.antMatchers("/user/create/**").permitAll()
.antMatchers("/user/created/**").permitAll()
.antMatchers("/user/update/**").permitAll()
.antMatchers("/user/updated/**").permitAll()
.antMatchers("/table/list").hasRole("ADMIN")
.antMatchers("/table/create").hasRole("USER")
.antMatchers("/table/created").hasRole("USER")
.anyRequest().denyAll();
Now I'm trying to replace all above antMatchers with:
.anyRequest().authenticated()
.withObjectPostProcessor(new ObjectPostProcessor<MyFilterSecurityMetadataSource>() {
@Override
public <O extends MyFilterSecurityMetadataSource> O postProcess(O object) {
object.getAttributes(object);
FilterInvocationSecurityMetadataSource metadataSource = new MyFilterSecurityMetadataSource();
if (object instanceof FilterInvocationSecurityMetadataSource) {
return (O) metadataSource.getAttributes(object);
}
return null;
}
}).anyRequest().denyAll();
And MyFilterSecurityMetadataSource is as follows (I'm not doing an actual lookup yet - I have a hard time getting to this filter):
public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
public List<ConfigAttribute> getAttributes(Object object) {
FilterInvocation fi = (FilterInvocation) object;
String fullRequestUrl = fi.getFullRequestUrl();
String requestUrl = fi.getRequestUrl();
String httpMethod = fi.getRequest().getMethod();
String contextPath = fi.getRequest().getContextPath();
System.out.println("Full request URL: " + fullRequestUrl);
System.out.println("Request URL: " + requestUrl);
System.out.println("HTTP Method: " + httpMethod);
System.out.println("Context path: " + contextPath);
List<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>(0);
// Lookup your database (or other source) using this information and populate the
// list of attributes
return configAttributes;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}
Maybe I need to configure a FilterSecurityInterceptor
instead of MyFilterSecurityMetadataSource
and pass this to the FilterSecurityInterceptor, I don't know. But then I have to use decisionManagers roleVotes bla. bla. I don't get it. It's quite hard to find a working sample regarding this specific subject. Sorry, my programming skills suck :)
答案 0 :(得分:2)
你有错误对象的后处理器。请使用以下
重写后处理器.anyRequest().authenticated().withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
public <O extends FilterSecurityInterceptor> O postProcess(
O fsi) {
FilterInvocationSecurityMetadataSource newSource = new MyFilterSecurityMetadataSource();
fsi.setSecurityMetadataSource(newSource);
return fsi;
}
})