Spring使用SpEL主体 [英] Spring Using SpEL Principal

查看:56
本文介绍了Spring使用SpEL主体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用本文档中的SpEL https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions 通过?#{principal.id}

I'm trying to use SpEL has in this document https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions to do a query filtering results by the ?#{principal.id}

问题是Spring返回异常

The problem is that Spring returns an exception

org.hibernate.QueryException:尚未设置所有命名参数:[1] [从产品p JOIN p.store s中选择p,p.store,p.category加入p.category c在哪里p.store.id =:id和p.keywords喜欢:keywordAND p.store.ownerId =?1];嵌套的例外是java.lang.IllegalArgumentException:org.hibernate.QueryException:不所有已命名的参数均已设置:[1] [选择p,p.store,产品p的类别p加盟p商店的s加盟p类别c地点p.store.id =:id和p.keywords像:keyword AND p.store.ownerId =?1]

org.hibernate.QueryException: Not all named parameters have been set: [1] [select p , p.store, p.category from Product p JOIN p.store s JOIN p.category c WHERE p.store.id = :id AND p.keywords LIKE :keyword AND p.store.ownerId = ?1 ]; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: Not all named parameters have been set: [1] [select p , p.store, p.category from Product p JOIN p.store s JOIN p.category c WHERE p.store.id = :id AND p.keywords LIKE :keyword AND p.store.ownerId = ?1 ]

我已经设置了以下代码,并且正在执行.

I have setup the following code and it is being executed.

@Service
public class SecurityEvaluationContextExtension extends EvaluationContextExtensionSupport {

    @Override
    public String getExtensionId() {
        return "security";
    }

    @Override
    public SecurityExpressionRoot getRootObject() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        System.out.println("SER >>>>> " + authentication.getPrincipal().toString() + " -- " );
        return new SecurityExpressionRoot(authentication) {};
    }
}

@Configuration
@EnableJpaRepositories
public class SecurityConfiguration {

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

}

我正在使用的服务器具有Spring Resource Server,因此使用转换波纹管从授权服务器获取ID.我确认代码可以很好地执行和翻译,但上面出现了异常.

I'm using this server has a Spring Resource Server and so using the translation bellow to get the Id from the Authorization server. I confirm the code is executing and translating well but I'm getting the exception above.

@Service
public class myPrincipalExtractor implements PrincipalExtractor {

    @Override
    public UserInfo extractPrincipal(Map<String, Object> map) {

        Map<String,Object> principal = null;

        if (map.containsKey("principal")) {
            principal = (Map<String, Object>) map.get("principal");
        }

        UserInfo user = new UserInfo();

        if (principal != null ) {
            if (principal.containsKey("id")) {
                user.setId(Long.parseLong(principal.get("id").toString()));
            }

            if (principal.containsKey("username")) {
                user.setUsername(principal.get("username").toString());
            }

            if (principal.containsKey("email")) {
                user.setEmail(principal.get("email").toString());
            }
        }

        System.out.println("----> " + user.getUsername() + " -> " + user.getId());

        return user;
    }
}

查询是...

@CrossOrigin
public interface StoreRepository extends CrudRepository<Store, Long>
{
    @Query("select p , p.store, p.category from Product p JOIN p.store s " +
            " JOIN p.category c " +
            " WHERE p.store.id = :id AND p.keywords LIKE %:keyword% AND p.store.ownerId = ?#{principal.id} ")
    List<Product> findByKeywordIgnoreCase(@Param("id") Long id , @Param("keyword") String keyword);
}

更多信息:

我在SecurityExpressionRoot中做了下面的代码,所以现在我知道当我将SpEL和ID和Username存在于对象中时,这确实会被调用.还尝试将返回的对象强制转换为Principal,并且发生了相同的问题.

I did this code bellow in the SecurityExpressionRoot so now I know this is really getting called when I place the SpEL and the ID and Username exist in the object. Also tried casting the returned object to Principal and the same problem happened.

AND p.store.ownerId =?#{principal.id}

AND p.store.ownerId = ?#{principal.id}

return new SecurityExpressionRoot(authentication) {
            @Override
            public UserInfo getPrincipal() {
                System.out.println("Fetching the principal has user " + authentication.getPrincipal().toString());
                return (UserInfo) authentication.getPrincipal();
            }
        };

推荐答案

在网站示例中(

In the website example (https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions) they specify you can use ?#{principal.id} and that really gets called when executing the code above but it fails on the @Query binding for some reason. However I tried running it with another example case

@Query("select p , p.store, p.category from Product p JOIN p.store s " +
            " JOIN p.category c " +
            " WHERE p.store.id = :id AND p.keywords LIKE %:keyword% AND p.store.ownerId = ?#{#security.principal.id} ")

这奏效了.我在这里找到了另一个示例: https://github.com/spring-projects/spring-data-examples/blob/master/jpa/security/src/main/java/example/springdata/jpa/security/SecureBusinessObjectRepository.java

And this worked. I found this other example here: https://github.com/spring-projects/spring-data-examples/blob/master/jpa/security/src/main/java/example/springdata/jpa/security/SecureBusinessObjectRepository.java

这篇关于Spring使用SpEL主体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆