gpt4 book ai didi

java - 在 Spring 中模拟用户

转载 作者:行者123 更新时间:2023-11-30 10:39:06 35 4
gpt4 key购买 nike

我想编写一个简单的测试,但我的 SecurityConfig 总是拒绝访问。这是我的配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserService userService;

@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new TokenAuthenticationFilter(userService), AnonymousAuthenticationFilter.class);
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);

//Options preflight
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll();

//ACL
http.authorizeRequests().antMatchers(HttpMethod.POST, "/auth/password").hasAnyRole("ADMIN", "CUSTOMER", "REFUGEE");
http.authorizeRequests().antMatchers("/auth/**").anonymous();

//Tags
http.authorizeRequests().antMatchers(HttpMethod.GET, "/tags").hasAnyRole("ADMIN", "CUSTOMER", "REFUGEE");
http.authorizeRequests().antMatchers(HttpMethod.GET, "/tags/recommendation").hasAnyRole("ADMIN", "CUSTOMER", "REFUGEE");
http.authorizeRequests().antMatchers(HttpMethod.POST, "/tags").hasAnyRole("ADMIN", "REFUGEE");
http.authorizeRequests().antMatchers(HttpMethod.GET, "/tags/recommendation/random").hasAnyRole("ADMIN", "CUSTOMER", "REFUGEE");
http.authorizeRequests().antMatchers(HttpMethod.PUT, "/tags").hasAnyRole("ADMIN");
http.authorizeRequests().antMatchers(HttpMethod.GET, "/tags/notapproved").hasAnyRole("ADMIN");
http.authorizeRequests().antMatchers(HttpMethod.PUT, "/tags/approve/{id}").hasAnyRole("ADMIN");
}

以及 AuthenticationFilter:

public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

private UserService userService;

public TokenAuthenticationFilter(UserService userService) {
super("/");
this.userService = userService;
}

private final String HEADER_SECURITY_TOKEN = "Authorization";
private final String PARAMETER_SECURITY_TOKEN = "access_token";
private String token = "";

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;

this.token = request.getHeader(HEADER_SECURITY_TOKEN);
if ("".equals(this.token) || this.token == null) {
this.token = request.getParameter(PARAMETER_SECURITY_TOKEN);
}

//Attempt to authenticate
Authentication authResult;
authResult = attemptAuthentication(request, response);
if (authResult == null) {
chain.doFilter(request, response);
} else {
successfulAuthentication(request, response, chain, authResult);
}
}

/**
* Attempt to authenticate request - basically just pass over to another
* method to authenticate request headers
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
Authentication userAuthenticationToken = authUserByToken();
if (userAuthenticationToken == null) {
//throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token"));
}
return userAuthenticationToken;
}

/**
* authenticate the user based on token, mobile app secret & user agent
*
* @return
*/
private Authentication authUserByToken() {
Authentication securityToken = null;
try {
User user = userService.findUserByAccessToken(this.token);
securityToken = new PreAuthenticatedAuthenticationToken(
user, null, user.getAuthorities());
} catch (Exception e) {
logger.error("Authenticate user by token error: ", e);
}
return securityToken;
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
SecurityContextHolder.getContext().setAuthentication(authResult);
chain.doFilter(request, response);
}

简单测试:

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring/test/test-servlet.xml"})
@WebAppConfiguration
public class TagControllerTest {

private MockMvc mockMvc;

private TagService tagServiceMock;

@Autowired
private FilterChainProxy springSecurityFilterChain;

@Resource
private WebApplicationContext webApplicationContext;

@Before
public void setUp() {
tagServiceMock = mock(TagService.class);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext)
.addFilters(this.springSecurityFilterChain)
.build();
}

public TagControllerTest() {
}

/**
* Test of getAllTags method, of class TagController.
*/
@Test
public void testGetAllTags() throws Exception {
List<Tags> tagsList = new ArrayList<>();
tagsList.add(new Tags((long) 1, "test", 2, 1));
tagsList.add(new Tags((long) 2, "test2", 4, 0));
User user = TestUtil.EMPTY_USER;
String query = "";
String notIncluded = "";
Integer limit = 8;
Integer start = 0;
Language language = new Language(0);
Boolean approved = false;

when(tagServiceMock.findTagsByQuery(user, query, limit, start, language, approved)).thenReturn(tagsList);
when(tagServiceMock.findTags(user, limit, start, language)).thenReturn(tagsList);



SecurityContextHolder.getContext().setAuthentication(TestUtil.getPrincipal("ROLE_ADMIN"));

mockMvc.perform(get("/tags").with(securityContext(SecurityContextHolder.getContext())).header("host", "localhost:80"))
.andExpect(status().isOk())
.andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].id", is(1)))
.andExpect(jsonPath("$[1].id", is(2)))
.andExpect(jsonPath("$[0].label", is("test")))
.andExpect(jsonPath("$[1].label", is("test2")))
.andExpect(jsonPath("$[0].count", is(2)))
.andExpect(jsonPath("$[1].count", is(4)))
.andExpect(jsonPath("$[0].approved", is(1)))
.andExpect(jsonPath("$[1].approved", is(0)));

verify(tagServiceMock, times(1)).findTagsByQuery(user, query, limit, start, language, approved);
verifyNoMoreInteractions(tagServiceMock);

}

问题是,我总是收到 403 -> 拒绝访问。这是因为 TokenAuthenticationFilter。如果我使用正确的访问 token 设置名为“授权”的 header (正确意味着由实际用户使用),那么它就可以工作。但我想那不是单元测试应该的样子。那么该怎么办?如何设置角色并传递SecurityFilter?

最佳答案

如果您不进行应包含它的集成测试,则应出于测试目的关闭 Spring 安全性。

关于java - 在 Spring 中模拟用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39426841/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com