2016-06-13 2 views
0

Я пытаюсь реализовать метод Security с помощью @PreAuthorize.Spring Security, похоже, игнорирует определенную услугу

Spring Версия: 4.2.3.Release Spring Security: 4.0.3.Release

я реализовал CustomPermissionEvaluator. Я заметил, что он работает нормально, за исключением 1 службы, где hasPmerission не вызывается. Я знаю это, потому что я получаю сообщение протоколирования от hasPermission/или в ошибочном случае не получают журнал:

public boolean hasPermission(Authentication authentication, Object o, Object o1) { 
    logger.info("Call to hasPermission with "+o+" and "+o1); 
... 
} 

Моя конфигурация Spring выглядит следующим образом:

@Configuration 
@ComponentScan 
public class RootConfiguration { 
} 

MVC Config

@EnableWebMvc 
@Configuration 
@ComponentScan({"OntoRais.*"}) 
@PropertySource("classpath:application.properties") 
@EnableGlobalMethodSecurity(prePostEnabled=true) 
public class MvcConfiguration extends WebMvcConfigurerAdapter{ 


@Bean 
public ViewResolver getViewResolver(){ 
    InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 
    resolver.setPrefix("/WEB-INF/views/"); 
    resolver.setSuffix(".jsp"); 
    return resolver; 
} 

@Override 
public void addResourceHandlers(ResourceHandlerRegistry registry) { 
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); 

    registry.addResourceHandler("swagger-ui.html") 
      .addResourceLocations("classpath:/META-INF/resources/"); 

    registry.addResourceHandler("/webjars/**") 
      .addResourceLocations("classpath:/META-INF/resources/webjars/"); 
} 

@Bean 
public static PropertySourcesPlaceholderConfigurer propertyConfigIn()  { 
    return new PropertySourcesPlaceholderConfigurer(); 
} 


@Bean(name="multipartResolver") 
public CommonsMultipartResolver commonsMultipartResolver(){ 
    CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); 
    commonsMultipartResolver.setDefaultEncoding("utf-8"); 
    commonsMultipartResolver.setMaxUploadSize(50000000); 
    return commonsMultipartResolver; 
} 
} 

Метод безопасности Config:

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
@ComponentScan 
public class MethodSecurityConfiguration extends  GlobalMethodSecurityConfiguration { 

@Autowired 
private CustomPermissionEvaluator permissionEvaluator; 

@Override 
protected MethodSecurityExpressionHandler createExpressionHandler() { 
    DefaultMethodSecurityExpressionHandler handler 
      = new DefaultMethodSecurityExpressionHandler(); 
    handler.setPermissionEvaluator(permissionEvaluator); 
    return handler; 
} 


public CustomPermissionEvaluator getPermissionEvaluator() { 
    return permissionEvaluator; 
} 

public void setPermissionEvaluator(CustomPermissionEvaluator permissionEvaluator) { 
    this.permissionEvaluator = permissionEvaluator; 
} 
} 

Initializer:

@Configuration 
@EnableSpringConfigured 
public class MessageWebApplicationInitializer extends 
    AbstractAnnotationConfigDispatcherServletInitializer { 

@Override 
public void onStartup(ServletContext servletContext) throws ServletException { 
    servletContext.addListener(org.springframework.web.context.request.RequestContextListener.class); 
    super.onStartup(servletContext); 
} 

@Override 
protected Class<?>[] getRootConfigClasses() { 
    return new Class[] { MvcConfiguration.class }; 
} 

@Override 
protected Class<?>[] getServletConfigClasses() { 
    return null; 
} 

@Override 
protected String[] getServletMappings() { 
    return new String[]{"/"}; 
} 

@Override 
protected Filter[] getServletFilters() { 

    return new Filter[]{new HiddenHttpMethodFilter(), 
      new OpenEntityManagerInViewFilter(), 
      new DelegatingFilterProxy("springSecurityFilterChain") 
    }; 
} 
} 

Security Config:

@Configuration 
@EnableWebSecurity 
@ComponentScan 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

@Autowired 
OntoRAISUserDetailsService ontoRAISUserDetailsService; 


@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http. 
      formLogin(). 
      and(). 
      logout(). 
      and(). 
      authorizeRequests(). 
      antMatchers("/login").permitAll(). 
      anyRequest().authenticated(). 
      and().csrf().disable(); 

} 

@Autowired 
@Override 
public void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.userDetailsService(ontoRAISUserDetailsService); 
    auth.authenticationProvider(authenticationProvider()); 

} 

@Bean 
public DaoAuthenticationProvider authenticationProvider() { 
    DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); 
    authenticationProvider.setUserDetailsService(ontoRAISUserDetailsService); 
    authenticationProvider.setPasswordEncoder(passwordEncoder()); 
    return authenticationProvider; 
} 


@Bean 
public BCryptPasswordEncoder passwordEncoder() { 
    return new BCryptPasswordEncoder(); 
} 

public OntoRAISUserDetailsService getOntoRAISUserDetailsService() { 
    return ontoRAISUserDetailsService; 
} 

public void setOntoRAISUserDetailsService(OntoRAISUserDetailsService ontoRAISUserDetailsService) { 
    this.ontoRAISUserDetailsService = ontoRAISUserDetailsService; 
} 

Служба в вопросе:

@Service 
public class StakeholderService { 

@Autowired 
private OntopManager om; 

private static final Logger logger = LoggerFactory.getLogger("OntoRais"); 

public OntopManager getOm() { 
    return om; 
} 

public void setOm(OntopManager om) { 
    this.om = om; 
} 

@PreAuthorize("hasPermission(#stakeholderType, 'Create_StakeholderType')") 
public void createStakeholderType(StakeholderType stakeholderType) { 
    try { 
     logger.info("Create stakeholder type in service layer"); 
     List<OBDADataSource> sources = om.getObdaModel().getSources(); 
     OBDAMappingAxiom mapping = om.getObdaModel().getMapping(new URI("genertatedURI"), MappingList.StakheholderType()); 

     HashMap<String, String> values = new HashMap<>(); 
     values.put("stakeholderName", stakeholderType.getLabel()); 

     String query = ClassSQLHelper.generateSQLCreateSatement(mapping.getSourceQuery(), values); 
     SQLHelper.executeSQL(query, sources.get(0)); 

    } catch (URISyntaxException e) { 
     logger.error(e.getMessage()); 
    } 
} 

И контроллер, от которого я называю служебный слой:

@Api(description = "Operations related to Stakeholders") 
@RestController 
public class StakeholderController { 

@Autowired 
private OntopManager om; 

@Autowired 
StakeholderService stakeholderService; 

@Autowired 
ProjectService projectService; 

private static final Logger logger =  LoggerFactory.getLogger("OntoRais"); 

... 

/** 
* Add a new Stakeholder Type 
* 
* @param stakeholdertype The new Stakeholder to be added. 
* @return 
*/ 
@ApiOperation(value = "Add new stakeholder type", 
     notes = "", 
     response = ResponseResource.class, 
     responseContainer = "Object") 
@JsonView(Views.Details.class) 
@RequestMapping(value = "/api/stakeholder/types", method = RequestMethod.POST) 
public ResponseEntity<List<StakeholderType>> addStakeholderType(@RequestBody StakeholderType stakeholdertype) { 
    logger.info("Add Stakeholder type in controller"); 
    getStakeholderService().createStakeholderType(stakeholdertype); 
    return getStakeholderTypes(); 
} 

При вызове API/заинтересованных сторон/типов»с методом POST = Это мой отладочный вывод:

Add Stakeholder type in controller 
Create stakeholder type in service layer 
INSERT INTO prefix_http_www_ontorais_de_stakeholdertype(id,stakeholderName) VALUES(DEFAULT,'TESTEWRTERETE'); 

Как вы можете видеть бревно из hasPermission нет -> не называется. Я вижу, что метод вызывается из моих других аннотаций sercurity в других объектах службы.

Аналогичная служба, которая правильно вызывает hasPermission, как ожидается, просто для сравнения:

@Service 
public class OrganisationService { 

private static final Logger logger = LoggerFactory.getLogger("OntoRais"); 
@Autowired 
private OntopManager om; 

@Autowired 
private ProjectService projectService; 

... 

@PreAuthorize("hasAuthority('Add_Organisation')") 
public void addOrganisation(Organisation organisation) { 
    List<OBDADataSource> sources = om.getObdaModel().getSources(); 

    OBDAMappingAxiom mapping = null; 
    try { 
     mapping = om.getObdaModel().getMapping(new URI("genertatedURI"), MappingList.OrganisationMapping()); 
    } catch (URISyntaxException e) { 
     e.printStackTrace(); 
    } 

    HashMap<String, String> valueMap = new HashMap<>(); 
    valueMap.put("organisationName", organisation.getName()); 
    valueMap.put("organisationDescription", organisation.getDescription()); 

    String query = ClassSQLHelper.generateSQLCreateSatement(mapping.getSourceQuery(), valueMap); 

    SQLHelper.executeSQL(query, sources.get(0)); 
} 

Любые намеки на то, что я делаю неправильно/отсутствует/слеп для очень приветствуются спасибо.

Бенедикт

+0

'OntoRais. *' Не действительное имя пакета.'StakeholderService' не реализует интерфейс, поэтому для того, чтобы' @ PreAuthorize' работал с библиотекой, такой как cglib или javassist, должен быть включен. В чем разница между вашими услугами? – zeroflagL

+0

Хорошо изменил мой компонент сканирования в '@ComponentScan ({ "OntoRais.api", "OntoRais.datalayer.database.service", "OntoRais.security", "OntoRais.datalayer.ontology.ontop", «OntoRais .datalayer.ontology.service ", " OntoRais.config " })'. Ни один из моих служб не реализует интерфейс. Разве проблема не возникает во всех моих сервисах? Я не могу найти разницы в сервисах. Чтобы быть уверенным, я включу рабочую службу в исходный вопрос. – bwright

+0

Если никакая служба не реализует интерфейс, то проблема, конечно же, является чем-то другим. Я думаю, что '@ComponentScan ({« OntoRais »})' должно быть достаточно. В 'StakeholderController', что такое код для' getStakeholderService() '? Если он не вернет защищенный прокси-сервер, это будет проблемой. Вы можете добавить точку останова в свой метод сервиса и посмотреть на стек вызовов. – zeroflagL

ответ

0

Ok я нашел проблему, и решение.

Проблема заключалась в том, что мой CustomPermissionEvaluator зависел от метода внутри StakeholderService. Несмотря на то, что этот метод не был обеспечен, это привело к тому, что Spring не смог проксировать объект, тем самым предотвращая любые проверки безопасности.

Несмотря на то, что это плохая идея, чтобы использовать объект службы слоя в PermissionEvaluator, возможно, кто-то может представить подробную информацию о точных последствиях, так как я определенно не специалист в весеннем sercurity

Смежные вопросы