【发布时间】:2015-05-24 22:17:31
【问题描述】:
我是 Spring、SpringSecurity 和 Boot 的新手——尝试创建一个 web 应用程序,我必须在数据库中查找用户是否有权访问请求的 URL。我已经设法使身份验证工作(即带有 loadUserByUsername 的 UserDetailService)。在数据库中,我有一个用于用户、组、角色的表,最后一个用于包含 URL 和配置属性(通常等于角色)的 URL。
所以我有这个工作配置(顺便说一下,我正在尝试用 Java 配置所有内容 - 不使用 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();
现在我正在尝试将以上所有 antMatchers 替换为:
.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();
MyFilterSecurityMetadataSource 如下(我还没有进行实际查找 - 我很难找到这个过滤器):
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);
}
}
也许我需要配置一个FilterSecurityInterceptor 而不是MyFilterSecurityMetadataSource 并将其传递给FilterSecurityInterceptor,我不知道。但后来我不得不使用decisionManagers roleVotes bla。布拉。我不明白。很难找到关于这个特定主题的工作样本。抱歉,我的编程技术很烂:)
【问题讨论】:
-
有几个 SO 主题但没有人帮助:stackoverflow.com/questions/10979756/…
-
也无法完成这项工作:stackoverflow.com/questions/8381776/…。也许是因为它底部有一个我不知道如何使用的xml conf。
-
您能解释一下 getAttributes 方法中应该写什么而不是 cmets 吗?网址列表?角色列表?这些之间的映射?另一个问题是:我可以使用此解决方案根据用户名和密码配置授权吗?
标签: spring-security spring-java-config