在Spring Security中尝试访问登录页面时访问被拒绝异常

ash*_*ram 5 java spring spring-security access-denied spring-java-config

我正在使用基于Java的Spring Security。我已经创建了自定义访问决策投票人impl。

但是,当我运行该应用程序时,无法打开登录页面,因为它显示访问被拒绝。

在我添加了自定义访问决策投票人impl之后,就发生了这种情况。我猜问题是由于自定义AccessDecisionVoter中的以下代码。

if(authentication instanceof AnonymousAuthenticationToken)
            return ACCESS_DENIED;
Run Code Online (Sandbox Code Playgroud)

但是我需要这样做,以便不检查未登录用户的权限。

它进入无限循环,登录页面,访问决策投票者,访问被拒绝,登录页面等等。

下面是spring安全配置代码。

@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);
    }

}
Run Code Online (Sandbox Code Playgroud)

和我的自定义选民展示

@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; 
Run Code Online (Sandbox Code Playgroud)

另外,当我从选民中删除以下几行内容时,如果用户未登录并尝试访问受保护的页面,它将继续进行。它应该已经重定向到登录页面。

if(authentication instanceof AnonymousAuthenticationToken)
                return ACCESS_DENIED;
Run Code Online (Sandbox Code Playgroud)

这是我第一次尝试使用Spring Boot。因此,我不确定所有配置问题。

antMatchers的顺序有什么问题吗?

请帮忙。

Tee*_*nen 2

如果我正确地理解了这一点,您正在尝试通过返回 ACCESS_DENIED 进行匿名身份验证来解决用户匿名登录的问题。那可不好。删除该自定义代码,然后在安全配置中执行此操作:

anyRequest().hasRole("USER")
Run Code Online (Sandbox Code Playgroud)

然后,确保用户登录时具有所需的角色。

另一种方法是禁用匿名登录,这样您就不需要角色(从长远来看,不建议这样做)。

http.anonymous().disable()
Run Code Online (Sandbox Code Playgroud)