Spring Test & Security: Làm thế nào để giả mạo xác thực?


124

Tôi đang cố gắng tìm ra cách kiểm tra đơn vị xem URL của bộ điều khiển của tôi có được bảo mật đúng cách hay không. Đề phòng trường hợp ai đó thay đổi mọi thứ và vô tình xóa cài đặt bảo mật.

Phương thức bộ điều khiển của tôi trông giống như sau:

@RequestMapping("/api/v1/resource/test") 
@Secured("ROLE_USER")
public @ResonseBody String test() {
    return "test";
}

Tôi đã thiết lập WebTestEnosystem như sau:

import javax.annotation.Resource;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.junit.Before;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({ 
        "file:src/main/webapp/WEB-INF/spring/security.xml",
        "file:src/main/webapp/WEB-INF/spring/applicationContext.xml",
        "file:src/main/webapp/WEB-INF/spring/servlet-context.xml" })
public class WebappTestEnvironment2 {

    @Resource
    private FilterChainProxy springSecurityFilterChain;

    @Autowired
    @Qualifier("databaseUserService")
    protected UserDetailsService userDetailsService;

    @Autowired
    private WebApplicationContext wac;

    @Autowired
    protected DataSource dataSource;

    protected MockMvc mockMvc;

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    protected UsernamePasswordAuthenticationToken getPrincipal(String username) {

        UserDetails user = this.userDetailsService.loadUserByUsername(username);

        UsernamePasswordAuthenticationToken authentication = 
                new UsernamePasswordAuthenticationToken(
                        user, 
                        user.getPassword(), 
                        user.getAuthorities());

        return authentication;
    }

    @Before
    public void setupMockMvc() throws NamingException {

        // setup mock MVC
        this.mockMvc = MockMvcBuilders
                .webAppContextSetup(this.wac)
                .addFilters(this.springSecurityFilterChain)
                .build();
    }
}

Trong thử nghiệm thực tế của tôi, tôi đã cố gắng làm một cái gì đó như sau:

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Test;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;

import eu.ubicon.webapp.test.WebappTestEnvironment;

public class CopyOfClaimTest extends WebappTestEnvironment {

    @Test
    public void signedIn() throws Exception {

        UsernamePasswordAuthenticationToken principal = 
                this.getPrincipal("test1");

        SecurityContextHolder.getContext().setAuthentication(principal);        

        super.mockMvc
            .perform(
                    get("/api/v1/resource/test")
//                    .principal(principal)
                    .session(session))
            .andExpect(status().isOk());
    }

}

Tôi đã chọn cái này ở đây:

Tuy nhiên, nếu người ta quan sát kỹ, điều này chỉ hữu ích khi không gửi yêu cầu thực tế đến URL, nhưng chỉ khi kiểm tra dịch vụ ở cấp độ chức năng. Trong trường hợp của tôi, một ngoại lệ "quyền truy cập bị từ chối" đã được đưa ra:

org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) ~[spring-security-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206) ~[spring-security-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:60) ~[spring-security-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.1.RELEASE.jar:3.2.1.RELEASE]
        ...

Hai thông báo nhật ký sau đây đáng chú ý về cơ bản nói rằng không có người dùng nào được xác thực cho biết rằng thiết lập Principalkhông hoạt động hoặc nó đã bị ghi đè.

14:20:34.454 [main] DEBUG o.s.s.a.i.a.MethodSecurityInterceptor - Secure object: ReflectiveMethodInvocation: public java.util.List test.TestController.test(); target is of class [test.TestController]; Attributes: [ROLE_USER]
14:20:34.454 [main] DEBUG o.s.s.a.i.a.MethodSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS

Tên công ty của bạn, eu.ubicon, được hiển thị trong lần nhập của bạn. Đó không phải là một rủi ro bảo mật?
Kyle Bridenstine

2
Xin chào, cảm ơn vì nhận xét! Tôi không thể hiểu tại sao mặc dù. Dù sao nó cũng là phần mềm nguồn mở. Nếu bạn quan tâm, hãy xem bitbucket.org/ubicon/ubicon (hoặc bitbucket.org/dmir_wue/everyaware để biết bản fork mới nhất). Hãy cho tôi biết nếu tôi bỏ lỡ điều gì đó.
Martin Becker

Kiểm tra giải pháp này (câu trả lời dành cho mùa xuân 4): stackoverflow.com/questions/14308341/…
Nagy Attila

Câu trả lời:


101

Tìm kiếm câu trả lời Tôi không thể tìm thấy bất kỳ giải pháp nào dễ dàng và linh hoạt đồng thời, sau đó tôi tìm thấy Tham chiếu bảo mật mùa xuân và tôi nhận ra rằng có những giải pháp gần như hoàn hảo. Các giải pháp AOP thường là những giải pháp tốt nhất để thử nghiệm và Spring cung cấp cho nó @WithMockUser, @WithUserDetails@WithSecurityContexttrong cấu trúc này:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <version>4.2.2.RELEASE</version>
    <scope>test</scope>
</dependency>

Trong hầu hết các trường hợp, hãy @WithUserDetailstập hợp sự linh hoạt và sức mạnh mà tôi cần.

@WithUserDetails hoạt động như thế nào?

Về cơ bản, bạn chỉ cần tạo một tùy chỉnh UserDetailsServicevới tất cả các hồ sơ người dùng có thể mà bạn muốn kiểm tra. Ví dụ

@TestConfiguration
public class SpringSecurityWebAuxTestConfig {

    @Bean
    @Primary
    public UserDetailsService userDetailsService() {
        User basicUser = new UserImpl("Basic User", "user@company.com", "password");
        UserActive basicActiveUser = new UserActive(basicUser, Arrays.asList(
                new SimpleGrantedAuthority("ROLE_USER"),
                new SimpleGrantedAuthority("PERM_FOO_READ")
        ));

        User managerUser = new UserImpl("Manager User", "manager@company.com", "password");
        UserActive managerActiveUser = new UserActive(managerUser, Arrays.asList(
                new SimpleGrantedAuthority("ROLE_MANAGER"),
                new SimpleGrantedAuthority("PERM_FOO_READ"),
                new SimpleGrantedAuthority("PERM_FOO_WRITE"),
                new SimpleGrantedAuthority("PERM_FOO_MANAGE")
        ));

        return new InMemoryUserDetailsManager(Arrays.asList(
                basicActiveUser, managerActiveUser
        ));
    }
}

Bây giờ chúng tôi đã có người dùng của mình, vì vậy hãy tưởng tượng chúng tôi muốn kiểm tra điều khiển truy cập cho chức năng điều khiển này:

@RestController
@RequestMapping("/foo")
public class FooController {

    @Secured("ROLE_MANAGER")
    @GetMapping("/salute")
    public String saluteYourManager(@AuthenticationPrincipal User activeUser)
    {
        return String.format("Hi %s. Foo salutes you!", activeUser.getUsername());
    }
}

Ở đây chúng ta có một get ánh xạ chức năng để các tuyến đường / foo / chào và chúng tôi đang thử nghiệm một vai trò dựa an ninh với các @Securedchú thích, mặc dù bạn có thể kiểm tra @PreAuthorize@PostAuthorizelà tốt. Hãy tạo hai bài kiểm tra, một để kiểm tra xem người dùng hợp lệ có thể thấy phản ứng chào này hay không và kiểm tra kia để kiểm tra xem nó có thực sự bị cấm hay không.

@RunWith(SpringRunner.class)
@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
        classes = SpringSecurityWebAuxTestConfig.class
)
@AutoConfigureMockMvc
public class WebApplicationSecurityTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithUserDetails("manager@company.com")
    public void givenManagerUser_whenGetFooSalute_thenOk() throws Exception
    {
        mockMvc.perform(MockMvcRequestBuilders.get("/foo/salute")
                .accept(MediaType.ALL))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("manager@company.com")));
    }

    @Test
    @WithUserDetails("user@company.com")
    public void givenBasicUser_whenGetFooSalute_thenForbidden() throws Exception
    {
        mockMvc.perform(MockMvcRequestBuilders.get("/foo/salute")
                .accept(MediaType.ALL))
                .andExpect(status().isForbidden());
    }
}

Như bạn thấy, chúng tôi đã nhập SpringSecurityWebAuxTestConfigđể cung cấp cho người dùng của chúng tôi để thử nghiệm. Mỗi cái được sử dụng trong trường hợp thử nghiệm tương ứng của nó chỉ bằng cách sử dụng một chú thích đơn giản, giảm mã và độ phức tạp.

Sử dụng tốt hơn @WithMockUser để bảo mật dựa trên vai trò đơn giản hơn

Như bạn thấy @WithUserDetailscó tất cả sự linh hoạt bạn cần cho hầu hết các ứng dụng của mình. Nó cho phép bạn sử dụng người dùng tùy chỉnh với bất kỳ GrantedAuthority nào, như vai trò hoặc quyền. Nhưng nếu bạn chỉ đang làm việc với các vai trò, việc kiểm tra thậm chí có thể dễ dàng hơn và bạn có thể tránh xây dựng một tùy chỉnh UserDetailsService. Trong những trường hợp như vậy, hãy chỉ định sự kết hợp đơn giản của người dùng, mật khẩu và vai trò với @WithMockUser .

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(
    factory = WithMockUserSecurityContextFactory.class
)
public @interface WithMockUser {
    String value() default "user";

    String username() default "";

    String[] roles() default {"USER"};

    String password() default "password";
}

Chú thích xác định các giá trị mặc định cho người dùng rất cơ bản. Như trong trường hợp của chúng tôi, tuyến đường chúng tôi đang thử nghiệm chỉ yêu cầu người dùng được xác thực là người quản lý, chúng tôi có thể bỏ sử dụng SpringSecurityWebAuxTestConfigvà thực hiện việc này.

@Test
@WithMockUser(roles = "MANAGER")
public void givenManagerUser_whenGetFooSalute_thenOk() throws Exception
{
    mockMvc.perform(MockMvcRequestBuilders.get("/foo/salute")
            .accept(MediaType.ALL))
            .andExpect(status().isOk())
            .andExpect(content().string(containsString("user")));
}

Lưu ý rằng bây giờ thay vì user manager@company.com, chúng tôi nhận được mặc định được cung cấp bởi @WithMockUser: user ; nhưng nó sẽ không quan trọng bởi vì những gì chúng ta thực sự quan tâm là vai trò của mình: ROLE_MANAGER.

Kết luận

Như bạn thấy với các chú thích @WithUserDetails@WithMockUserchúng tôi có thể chuyển đổi giữa các kịch bản người dùng được xác thực khác nhau mà không cần xây dựng các lớp khác với kiến ​​trúc của chúng tôi chỉ để thực hiện các thử nghiệm đơn giản. Nó cũng khuyên bạn nên xem @WithSecurityContext hoạt động như thế nào để linh hoạt hơn nữa.


Làm thế nào để chế nhạo nhiều người dùng ? Ví dụ: yêu cầu đầu tiên được gửi bởi tom, trong khi yêu cầu thứ hai là bởi jerry?
ch271828n

Bạn có thể tạo một hàm trong đó bài kiểm tra của bạn là tom và tạo một bài kiểm tra khác với cùng một logic và kiểm tra nó với Jerry. Sẽ có một kết quả cụ thể cho mỗi bài kiểm tra, do đó sẽ có các xác nhận khác nhau và nếu một bài kiểm tra không thành công, nó sẽ cho bạn biết bằng tên của người dùng / vai trò nào không hoạt động. Hãy nhớ rằng trong một yêu cầu, người dùng chỉ có thể là một, vì vậy việc chỉ định nhiều người dùng trong một yêu cầu không có ý nghĩa.
EliuX

Xin lỗi, ý tôi là kịch bản ví dụ như vậy: Chúng tôi kiểm tra điều đó, tom tạo ra một bài báo bí mật, sau đó jerry cố đọc bài báo đó và jerry sẽ không nhìn thấy nó (vì nó là bí mật). Vì vậy, trong trường hợp này, nó là một bài kiểm tra đơn vị ...
ch271828n

Nó trông khá giống với BasicUserManager Userkịch bản được đưa ra trong câu trả lời. Khái niệm chính là thay vì quan tâm đến người dùng, chúng tôi thực sự quan tâm đến vai trò của họ, nhưng mỗi thử nghiệm đó, nằm trong cùng một đơn vị thử nghiệm, thực sự đại diện cho các truy vấn khác nhau. được thực hiện bởi những người dùng khác nhau (với các vai trò khác nhau) đến cùng một điểm cuối.
EliuX

61

Kể từ Spring 4.0+, giải pháp tốt nhất là chú thích phương pháp thử nghiệm bằng @WithMockUser

@Test
@WithMockUser(username = "user1", password = "pwd", roles = "USER")
public void mytest1() throws Exception {
    mockMvc.perform(get("/someApi"))
        .andExpect(status().isOk());
}

Hãy nhớ thêm phần phụ thuộc sau vào dự án của bạn

'org.springframework.security:spring-security-test:4.2.3.RELEASE'

1
Mùa xuân thật tuyệt vời. Cảm ơn
TuGordoBello,

Câu trả lời tốt. Hơn nữa - bạn không cần phải sử dụng mockMvc, nhưng trong trường hợp nếu bạn đang sử dụng ví dụ: PagingAndSortingRepository từ springframework.data - bạn có thể gọi trực tiếp các phương thức từ kho lưu trữ (được chú thích bằng EL @PreAuthorize (......))
supertramp

50

Hóa ra là SecurityContextPersistenceFilter, là một phần của chuỗi bộ lọc Spring Security, luôn đặt lại của tôi SecurityContext, mà tôi đặt gọi SecurityContextHolder.getContext().setAuthentication(principal)(hoặc bằng cách sử dụng .principal(principal)phương thức). Bộ lọc này đặt SecurityContexttrong SecurityContextHoldervới một SecurityContexttừ SecurityContextRepository OVERWRITING mà tôi đã đặt trước đó. Kho lưu trữ là một HttpSessionSecurityContextRepositorytheo mặc định. Kiểm HttpSessionSecurityContextRepositorytra cái đã cho HttpRequestvà cố gắng truy cập cái tương ứng HttpSession. Nếu nó tồn tại, nó sẽ cố gắng đọc SecurityContexttừ HttpSession. Nếu điều này không thành công, kho lưu trữ sẽ tạo ra trống SecurityContext.

Do đó, giải pháp của tôi là chuyển một HttpSessioncùng với yêu cầu, yêu cầu này chứa SecurityContext:

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Test;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;

import eu.ubicon.webapp.test.WebappTestEnvironment;

public class Test extends WebappTestEnvironment {

    public static class MockSecurityContext implements SecurityContext {

        private static final long serialVersionUID = -1386535243513362694L;

        private Authentication authentication;

        public MockSecurityContext(Authentication authentication) {
            this.authentication = authentication;
        }

        @Override
        public Authentication getAuthentication() {
            return this.authentication;
        }

        @Override
        public void setAuthentication(Authentication authentication) {
            this.authentication = authentication;
        }
    }

    @Test
    public void signedIn() throws Exception {

        UsernamePasswordAuthenticationToken principal = 
                this.getPrincipal("test1");

        MockHttpSession session = new MockHttpSession();
        session.setAttribute(
                HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, 
                new MockSecurityContext(principal));


        super.mockMvc
            .perform(
                    get("/api/v1/resource/test")
                    .session(session))
            .andExpect(status().isOk());
    }
}

2
Chúng tôi vẫn chưa thêm hỗ trợ chính thức cho Spring Security. Xem jira.springsource.org/browse/SEC-2015 Một phác thảo cho nó trông sẽ như thế nào được chỉ định trong github.com/SpringSource/spring-test-mvc/blob/master/src/test/…
Rob Winch

Tôi không nghĩ rằng việc tạo một đối tượng Xác thực và thêm một phiên có thuộc tính tương ứng lại tệ như vậy. Bạn có nghĩ rằng đây là một "công việc xung quanh" hợp lệ? Tất nhiên, hỗ trợ trực tiếp sẽ rất tốt. Trông khá gọn gàng. Cảm ơn các liên kết!
Martin Becker

giải pháp tuyệt vời. đã làm cho tôi! chỉ là một vấn đề nhỏ với việc đặt tên cho phương thức được bảo vệ getPrincipal()mà theo ý kiến ​​của tôi là hơi sai lệch. lý tưởng là nó nên được đặt tên getAuthentication(). tương tự như vậy, trong signedIn()thử nghiệm của bạn , biến cục bộ nên được đặt tên authhoặc authenticationthay vìprincipal
Tanvir

Là gì "getPrincipal (" test1" ) ¿?? Bạn có thể expline nơi là nó mà Cảm ơn trước?
user2992476

@ user2992476 Nó có thể trả về một đối tượng kiểu UsernamePasswordAuthenticationToken. Ngoài ra, bạn tạo GrantedAuthority và xây dựng đối tượng này.
bluelurker

31

Thêm vào pom.xml:

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <version>4.0.0.RC2</version>
    </dependency>

và sử dụng org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessorscho yêu cầu ủy quyền. Xem cách sử dụng mẫu tại https://github.com/rwinch/spring-security-test-blog ( https://jira.spring.io/browse/SEC-2592 ).

Cập nhật:

4.0.0.RC2 hoạt động cho Spring-security 3.x. Đối với spring-security 4, spring-security-test trở thành một phần của spring-security ( http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#test , phiên bản giống nhau ).

Thiết lập đã được thay đổi: http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#test-mockmvc

public void setup() {
    mvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity())  
            .build();
}

Mẫu cho xác thực cơ bản: http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#testing-http-basic-authentication .


Điều này cũng đã khắc phục sự cố của tôi với việc nhận được 404 khi cố gắng đăng nhập qua bộ lọc bảo mật đăng nhập. Cảm ơn!
Ian Newland,

Xin chào, trong khi thử nghiệm như đã đề cập bởi GKislin. Tôi gặp lỗi sau "Xác thực không thành công UserDetailsService trả về null, là vi phạm hợp đồng giao diện". Bất kỳ đề nghị xin vui lòng. cuối cùng AuthenticationRequest auth = new AuthenticationRequest (); auth.setUsername (userId); auth.setPassword (mật khẩu); mockMvc.perform (post ("/ api / auth /"). content (json (auth)). contentType (MediaType.APPLICATION_JSON));
Sanjeev

7

Đây là một ví dụ cho những ai muốn Kiểm tra Cấu hình bảo mật Spring MockMvc bằng cách sử dụng xác thực cơ bản Base64.

String basicDigestHeaderValue = "Basic " + new String(Base64.encodeBase64(("<username>:<password>").getBytes()));
this.mockMvc.perform(get("</get/url>").header("Authorization", basicDigestHeaderValue).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());

Maven phụ thuộc

    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.3</version>
    </dependency>

3

Câu trả lời ngắn:

@Autowired
private WebApplicationContext webApplicationContext;

@Autowired
private Filter springSecurityFilterChain;

@Before
public void setUp() throws Exception {
    final MockHttpServletRequestBuilder defaultRequestBuilder = get("/dummy-path");
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext)
            .defaultRequest(defaultRequestBuilder)
            .alwaysDo(result -> setSessionBackOnRequestBuilder(defaultRequestBuilder, result.getRequest()))
            .apply(springSecurity(springSecurityFilterChain))
            .build();
}

private MockHttpServletRequest setSessionBackOnRequestBuilder(final MockHttpServletRequestBuilder requestBuilder,
                                                             final MockHttpServletRequest request) {
    requestBuilder.session((MockHttpSession) request.getSession());
    return request;
}

Sau khi thực hiện formLogintừ kiểm tra bảo mật mùa xuân, mỗi yêu cầu của bạn sẽ được tự động gọi là người dùng đã đăng nhập.

Câu trả lời dài:

Kiểm tra giải pháp này (câu trả lời là cho mùa xuân 4): Cách đăng nhập người dùng với thử nghiệm mvc mới mùa xuân 3.2


2

Các tùy chọn để tránh sử dụng SecurityContextHolder trong các thử nghiệm:

  • Tùy chọn 1 : Sử dụng mocks - Ý tôi là giả lập SecurityContextHolderbằng cách sử dụng một số thư viện giả - EasyMock chẳng hạn
  • Tùy chọn 2 : gói cuộc gọi SecurityContextHolder.get...trong mã của bạn trong một số dịch vụ - ví dụ như SecurityServiceImplvới phương thức getCurrentPrincipaltriển khai SecurityServicegiao diện và sau đó trong các thử nghiệm của bạn, bạn có thể chỉ cần tạo triển khai giả lập giao diện này trả về giá trị gốc mong muốn mà không cần quyền truy cập SecurityContextHolder.

Mh, có lẽ tôi không nhận được toàn bộ hình ảnh. Vấn đề của tôi là SecurityContextPersistenceFilter thay thế SecurityContext bằng SecurityContext từ một HttpSessionSecurityContextRepository, lần lượt đọc SecurityContext từ HttpSession tương ứng. Do đó, giải pháp sử dụng phiên. Về lệnh gọi tới SecurityContextHolder: Tôi đã chỉnh sửa câu trả lời của mình để không sử dụng lệnh gọi tới SecurityContextHolder nữa. Nhưng cũng không giới thiệu bất kỳ gói hoặc thư viện chế nhạo bổ sung nào. Bạn có nghĩ rằng, đây là một giải pháp tốt hơn?
Martin Becker

Xin lỗi, tôi không hiểu chính xác những gì bạn đang tìm kiếm và tôi không thể cung cấp câu trả lời tốt hơn giải pháp bạn đưa ra và - nó có vẻ là một lựa chọn tốt.
Pavla Nováková

Được rồi, cảm ơn. Tôi sẽ chấp nhận đề xuất của tôi như một giải pháp cho bây giờ.
Martin Becker
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.