【问题标题】:Can't access the pages of a spring project due to some misconfiguration由于配置错误,无法访问 spring 项目的页面
【发布时间】:2014-04-19 07:35:29
【问题描述】:

在我最近的 spring 项目中,我发现访问方法 (MethodSecurity) 的权限配置存在问题。我有这个 SecurityConfig 类:

@Autowired
private CustomAuthenticationProvider authenticationProvider;

public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .authenticationProvider(authenticationProvider);
}

/*@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
     return new CustomAuthenticationManager();
}*/

protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf()
            .disable()
        .authorizeRequests()
            .antMatchers("/erro/login").permitAll()
            .antMatchers("/bootstrap/**", "/jquery/**", "/extra/**", "/publico/**", "/erro/publico/**").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/acesso/login").permitAll()
            .loginProcessingUrl("/login").permitAll()
            .usernameParameter("login")
            .passwordParameter("senha")
            .successHandler(new CustomAuthenticationSuccessHandler())
            .failureHandler(new CustomAuthenticationFailureHandler())
            .and()
        .rememberMe()
            .key("lembrete")
            .useSecureCookie(true)
            .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/acesso/login").permitAll();
}

/*protected MethodSecurityExpressionHandler createExpressionHandler() {
    DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
    expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
    return expressionHandler;
}*/

在我的方法中(在控制器和服务类中),我有这个注释:

@RequestMapping(value="admin")
@PreAuthorize("hasRole('admin_main')")
public ModelAndView admin() {
    ModelAndView mav = new ModelAndView();
    mav.setViewName("privado/admin");
    return mav;
}

@RequestMapping(value="customer")
@PreAuthorize("hasRole('customer_main')")
public ModelAndView customer() {
    ModelAndView mav = new ModelAndView();
    mav.setViewName("privado/customer");
    return mav;
}

通过互联网阅读了一些文本,我学会了使用这个特定的注释,我应该实现一个自定义的 PermissionEvaluator,我这样做并在我的 SecurityConfig 的方法 createExpressionHandler() 中引用了这个类(现已注释)。

但是,尽管如此,当我运行我的项目并输入我的登录凭据时,我将被转发到我为我的应用程序配置的拒绝访问页面。任何人都可以指出如何在我的应用程序中正确配置此权限资源的方向?

更新

我的 CustomPermissionEvaluator.java

public class CustomPermissionEvaluator implements PermissionEvaluator {

    public CustomPermissionEvaluator() {
    }

    @Override
    public boolean hasPermission(Authentication arg0, Object arg1, Object arg2) {
        if (arg0 == null || !arg0.isAuthenticated())
            return false;
        else
            return arg0.getAuthorities().contains(arg1);
    }

    @Override
    public boolean hasPermission(Authentication arg0, Serializable arg1, String arg2, Object arg3) {
        throw new RuntimeException("Id-based permission evaluation not currently supported.");
    }

}

当我取消注释方法 createExpressionHandler() 并尝试运行应用程序时,我被告知我需要一个自定义 AuthenticatioManager,但我不知道如何实现最后一个。

更新

所以,我对我的 Custom AuthenticationManager 有了一个想法,它正在对用户进行身份验证,但我仍然无法从我的应用程序访问页面。

public class CustomAuthenticationManager implements AuthenticationManager {

    @Autowired
    private CustomAuthenticationProvider authenticationProvider;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        System.out.println("CustomAuthenticationManager.authenticate");
        this.createExpressionHandler();
        return authenticationProvider.authenticate(authentication);
    }

    protected MethodSecurityExpressionHandler createExpressionHandler() {
        System.out.println("CustomAuthenticationManager.createExpressionHandler");
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
        return expressionHandler;
    }

}

我尝试在我的 SecurityConfig 的方法 createExpressionHandler() 中调用 createExpressionHandler(),但也不起作用。

在这两种情况下,登录都已完成,但我无法访问任何页面。

更新

所以,我现在的情况是:

我的 SecurityConfig 引用了我的 CustomAuthenticationManager,它调用了我的 CustomAuthenticationProvider。

我有一个类 MethodSecurityConfig,引用了我的 CustomPermissionEvaluator:

@Configuration
@ComponentScan(value="com.spring.webapp.lojavirtual")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    protected MethodSecurityExpressionHandler createExpressionHandler() {
        System.out.println("MethodSecurityConfig.createExpressionHandler");
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
        return expressionHandler;
    }

}

那是我的 CustomPermissionEvaluator:

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {

    public CustomPermissionEvaluator() {
    }

    public boolean hasPermission(Authentication arg0, Object arg1) {
        System.out.println("CustomPermissionEvaluator.hasPermission");
        if (arg0 == null || !arg0.isAuthenticated())
            return false;
        else
            return arg0.getAuthorities().contains(arg1);
    }

    @Override
    public boolean hasPermission(Authentication arg0, Object arg1, Object arg2) {
        throw new RuntimeException("Id-based permission evaluation not currently supported.");
    }

    @Override
    public boolean hasPermission(Authentication arg0, Serializable arg1, String arg2, Object arg3) {
        throw new RuntimeException("Id-based permission evaluation not currently supported.");
    }

}

现在我遇到了主题中描述的错误:

SpelEvaluationException: EL1004E:(pos 0): Method call: Method hasPermission(java.lang.String) cannot be found on MethodSecurityExpressionRoot type

当我尝试在我的应用程序中执行登录时。关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: spring spring-mvc spring-security


    【解决方案1】:

    然后我解决这里提出的问题,从我的控制器更改方法中对 hasPermission 的调用。他们的最终代码是:

    @Controller
    @RequestMapping(value="privado")
    public class PrivadoController {
    
        @RequestMapping(value="admin")
        @PreAuthorize("hasPermission(#usuario, 'admin_main')")
        public ModelAndView admin() {
            ModelAndView mav = new ModelAndView();
            mav.setViewName("privado/admin");
            return mav;
        }
    
        @RequestMapping(value="customer")
        @PreAuthorize("hasPermission(#usuario, 'customer_main')")
        public ModelAndView customer() {
            ModelAndView mav = new ModelAndView();
            mav.setViewName("privado/customer");
            return mav;
        }
    
    }
    

    (现在我正在尝试找到替换#usuario 的正确参数,它返回一个空值,但这是另一个主题的主题)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-01
      • 2020-03-26
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 2021-06-01
      • 2022-01-10
      • 2015-08-30
      相关资源
      最近更新 更多