Spring 4 Rest @Query注释无法使用安全主体

时间:2017-08-16 02:06:01

标签: spring-security spring-data-jpa spring-el

我有一个简单的(此时仍然是一个演示程序)Spring程序(Spring Rest和Security)以简单的方式工作。通过JpaRepository,我可以获取所有(/ find由findAll()处理),GET一个(/ option / 1由findOne(Long id)处理),PUT和POST。

我的商业模式表明,登录用户只能看到他们有权使用的记录。所以findAll()应该返回三条记录,findOne(id)应该返回一个或零。

我相信我必须将它们与注释中的Principal对象联系起来。我尝试了各种各样的方案,但还没有想到春天想要我做什么。对于findAll(),我试过这个:

@Override
@Query("from Option o where o.id = 11")
public List<Option> findAll();

但是,findAll()仍会返回许多记录。

然后我尝试将我的查询与校长联系起来:

@Override
@Query("from Option o where o.id = ?#{ principal.id}")
public List<Option> findAll(); 

(我还试过?#{#principal.id})

这有趣地失败了。

  • 当它返回HTTP 500时,我告诉&#34;校长&#34;无法找到。
  • 一旦我重新配置我的程序,我得到了一个HTTP 404,这意味着我提出了错误的问题。但由于我不知道如何转储principal.id值(从界面登录?),我无法看到我做错了什么。

以下是我公开UserDetailsS​​ervice的方式:

@Service
public class JwtUserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

以下是我在pom.xml中配置主体的方法:

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-data</artifactId>
        <!-- <version>4.2.1.RELEASE</version> -->
    </dependency>

和Java:

@SuppressWarnings("SpringJavaAutowiringInspection")
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .userDetailsService(this.userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

我的问题是:

  • 为什么@Query(&#34;来自选项o,其中o.id = 11&#34;)只返回一条记录?
  • 我怎样才能告诉&#34; principal&#34;的属性,所以我可以判断它的ID是否是我认为的?
  • 我还应该问其他问题吗?

谢谢, 杰罗姆。

1 个答案:

答案 0 :(得分:2)

  

为什么@Query(&#34;来自选项o,其中o.id = 11&#34;)只返回一条记录?

因为这不是有效的JPQL查询。您的硬编码测试查询必须为@Query("SELECT o FROM Option o WHERE o.id = 11")

  

我怎样才能告诉&#34; principal&#34;的属性,所以我可以判断它的ID是否符合我的想法?

您必须为查询启用Spring Security SpEL功能。

@Configuration
@EnableJpaRepositories
class SecurityConfiguration {

    @Bean
    EvaluationContextExtension securityExtension() {
        return new SecurityEvaluationContextExtension();
    }
}

它解释了here

如果您有自定义?#{principal.id} - 使用UserDetails字段实施,现在id将有效。例如:

import org.springframework.security.core.userdetails.User;

public class HapaUserDetails extends User { //User implements UserDetails

    private final long id;

    //constructor and getters
}