由于一些配置错误,无法访问spring项目的页面

时间:2014-04-17 11:55:53

标签: spring spring-mvc spring-security

在我最近的春季项目中,我遇到了访问方法(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,但我不知道如何实现最后一个。

更新

所以,我对自定义身份验证管理器有一个想法,它正在验证用户身份,但我仍然无法从我的应用程序访问这些页面。

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(),但是也不行。

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

更新

所以,我目前的情况是:

My 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

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

1 个答案:

答案 0 :(得分:0)

然后我解决了这里提出的问题,在我的控制器的方法中改变了对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的正确参数,它返回一个空值,但这是另一个主题的主题。)