@WithMockUser与自定义用户实现 [英] @WithMockUser with custom User implementation

查看:852
本文介绍了@WithMockUser与自定义用户实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring OAuth2和JWT令牌来保护应用程序.我正在扩展 org.springframework.security.core.userdetails ,以便向令牌添加一些其他属性,然后可以将这些属性用于执行称为端点的授权.

I'm using spring OAuth2 and JWT tokens to secure an application. I am extending org.springframework.security.core.userdetails in order to add some additional attributes to the token which can then be used to perform authorization ones an endpoint is called.

public class CustomUser extends User {
     private Set<String> bookIds;

     public CustomUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {
         super(username, password, authorities);
     }

     public CustomUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
         super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
     }
}

我也有一个org.springframework.security.access.PermissionEvaluator的自定义实现,它能够反序列化令牌并检查自定义属性是否是其中的一部分,可以将其添加到控制器端点中.

I also have a custom implementation of org.springframework.security.access.PermissionEvaluator which is able to deserialize the token and check that the custom attributes are part of it which can be added to controller endpoints as such.

@PreAuthorize("hasPermission(authentication, #bookId,'read')")

现在一切正常,我可以通过邮递员测试我的应用程序,只有拥有有效JWT令牌且其bookIds设置的URL部分中具有bookID的用户才能访问资源

Now it all works fine, I can test my application through postman and only users with a valid JWT token that has bookID in the URL part of their bookIds set can access the resource as such

@PreAuthorize("hasPermission(authentication, #bookId,'read')")
@GetMapping(value = "api/books/{bookId}")
public Book getBook(@PathVariable String bookId) {}

但是,我正在努力对此进行测试,因为它是微服务应用程序的一部分,在该应用程序中,身份验证和服务不是同一项目的一部分,而是可以在单独的VM上运行.理想情况下,我希望能够在每个服务中模拟令牌,并在bookId集中添加所需的任何值. 我知道在春季4之后,我们可以使用@WithMockUser,但是据我所知,这仅限于用户名/密码/角色/授权,例如:

HOWEVER, I'm struggling to test this as this is part of a microservice application where authentication and services are not part of the same project and would run on separate VMs. IDEALLY, i'd like to be able to mock the token in each of the services and add whatever values I need inside of this bookId set. I know that after spring 4 we can use @WithMockUser, however, from what I can tell this is limited to username/password/role/authority, e.g. :

@WithMockUser(username = "ram", roles={"ADMIN"})

我真正想做的是扩展此注释以支持我的自定义属性'bookId',或在其中注入模拟集的方法.这有可能吗?如果没有,那我有什么选择,因为我无法在单元测试中调用身份验证提供程序,因为该实现将存在于单独的应用程序中托管的另一个spring上下文中.

What I'd really like to do is either extend this annotation to support my custom attribute 'bookId' or a way to inject a mock set in it. Is this possible, and if not, what are my alternatives, as I wouldn't be able to call my authentication provider in my unit tests as the implementation would live in another spring context hosted on a separate app.

非常感谢!

推荐答案

您可以使用@WithUserDetails批注.
如果您有一个用户名为"user1"的用户,则可以使用@WithUserDetails("user1")注释测试,它将以CustomUser主体执行,包括与"user1"相关联的自定义属性"bookId".
您可以在

You can use the @WithUserDetails annotation.
If you have a user with the username "user1", then you can annotate your test with @WithUserDetails("user1") and it will execute with a CustomUser principal, including the custom attribute "bookId" associated with "user1".
You can find more information about the annotation in the spring-security docs.

如果要获得更大的灵活性,还可以使用@WithSecurityContext批注.
这使您可以创建自己的注释,例如@WithMockCustomUser,您可以在其中自行设置安全上下文.
您可以在
spring中找到更多详细信息-安全文档.

If you want more flexibility, you can also use the @WithSecurityContext annotation.
This allows you to create your own annotation, e.g @WithMockCustomUser, where you set the security context yourself.
You can find more details in the spring-security docs.

还有一个选项,如果您使用MockMvc来运行测试,则可以使用

One more option, if you are using MockMvc to run your tests, it to use a request post processor.
Your test would look like this

mvc
    .perform(get("/api/books/1")
    .with(user(customUser)));

其中customUser是您在测试中创建的CustomUser的实例.

where customUser is an instance of CustomUser that you create in the test.

这篇关于@WithMockUser与自定义用户实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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