我正在使用基于Java的Spring安全机制。我创建了自定义访问决策投票者实现。
但是当我运行应用程序时,无法打开登录页面,因为它显示访问被拒绝。
这发生在我添加自定义访问决策投票者实现后。我猜测问题出在自定义AccessDecisionVoter中以下代码的原因。
if(authentication instanceof AnonymousAuthenticationToken)
return ACCESS_DENIED;
但我需要这样做,以便未登录用户不会受到权限检查的限制。
然而,它会进入无限循环:登录页面、访问决策投票器、访问被拒绝、登录页面等等。
下面是Spring Security配置代码。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private AffirmativeBased accessDecisionManager;
@Bean
@Autowired
public AffirmativeBased accessDecisionManager(AccessDecisionVoterImpl accessDecisionVoter) {
List<AccessDecisionVoter<?>> accessDecisionVoters = new ArrayList<AccessDecisionVoter<?>>();
accessDecisionVoters.add(accessDecisionVoter);
AffirmativeBased accessDecisionManager = new AffirmativeBased(accessDecisionVoters);
return accessDecisionManager;
}
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder(){
PasswordEncoder passwordEncoder = new PasswordEncoder();
passwordEncoder.setStringDigester(stringDigester());
return passwordEncoder;
}
@Bean
public PooledStringDigester stringDigester() {
PooledStringDigester psd = new PooledStringDigester();
psd.setPoolSize(2);
psd.setAlgorithm("SHA-256");
psd.setIterations(1000);
psd.setSaltSizeBytes(16);
psd.setSaltGenerator(randomSaltGenerator());
return psd;
}
@Bean
public RandomSaltGenerator randomSaltGenerator() {
RandomSaltGenerator randomSaltGenerator = new RandomSaltGenerator();
return randomSaltGenerator;
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/static/**")
.antMatchers("/i18n/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/checkLogin")
.defaultSuccessUrl("/home")
.failureUrl("/login?login_error=1")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?isLoggedOut=1")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/login**").permitAll()
.antMatchers("/error**").permitAll()
.antMatchers("/checkLogin**").permitAll()
.anyRequest()
.authenticated()
.accessDecisionManager(accessDecisionManager)
.and()
.exceptionHandling()
.accessDeniedPage("/accessDenied")
.and()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.invalidSessionUrl("/login")
.maximumSessions(1);
}
}
以及我的自定义投票者实现
@Component
public class AccessDecisionVoterImpl implements AccessDecisionVoter {
@Autowired
private ModuleService moduleService;
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class clazz) {
return true;
}
@Override
public int vote(Authentication authentication, Object object, Collection collection) {
// i have given this so that if user is not logged in then should not check permission at all
if(authentication instanceof AnonymousAuthenticationToken)
return ACCESS_DENIED;
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
String requestedOperation = request.getParameter("operation");
if (requestedOperation != null && !requestedOperation.isEmpty()){
String [] requestURISplit = request.getRequestURI().split("/");
String requestedModuleName = requestURISplit[2];
if(SecurityUtils.hasPermission(requestedModuleName, requestedOperation)){
return ACCESS_GRANTED;
}
} else {
return ACCESS_GRANTED;
}
return ACCESS_DENIED;
此外,如果我从我的投票者中删除以下行,如果用户未登录并尝试访问受保护的页面,则会继续访问。它应该重定向到登录页面。
if(authentication instanceof AnonymousAuthenticationToken)
return ACCESS_DENIED;
这是我第一次尝试使用Spring Boot。因此,我不确定所有的配置问题。
antMatchers的顺序是否有问题?
请帮忙。
AccessDecisionVoter
来实现此功能。您可以在antMatcher
中使用hasRole
来确保访问权限。 - Ali Dehghani//// some other code to check role module based permissions.
? - Ali Dehghani