বসন্ত পরীক্ষা ও সুরক্ষা: কীভাবে প্রমাণীকরণের উপহাস করবেন?


124

আমি যদি আমার কন্ট্রোলারগুলির ইউআরএলগুলি সঠিকভাবে সুরক্ষিত করা হয় তবে কীভাবে ইউনিট পরীক্ষা করব তা নির্ধারণ করার চেষ্টা করছিলাম। কেবলমাত্র কেউ যদি কাছাকাছি জিনিস পরিবর্তন করে এবং দুর্ঘটনাক্রমে সুরক্ষা সেটিংস সরিয়ে দেয়।

আমার নিয়ামক পদ্ধতিটি দেখতে এমন দেখাচ্ছে:

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

আমি এটির মতো একটি ওয়েব টেষ্ট পরিবেশ স্থাপন করেছি:

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();
    }
}

আমার প্রকৃত পরীক্ষায় আমি এরকম কিছু করার চেষ্টা করেছি:

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());
    }

}

আমি এটি এখানে তুলেছি:

তবুও যদি কেউ ঘনিষ্ঠভাবে দেখে তবে এটি কেবলমাত্র ইউআরএলগুলিতে প্রকৃত অনুরোধগুলি না প্রেরণে সহায়তা করে, তবে কেবলমাত্র কোনও কার্য স্তরের পরিষেবাগুলির পরীক্ষা করার সময়। আমার ক্ষেত্রে একটি "অ্যাক্সেস অস্বীকার" ব্যতিক্রম নিক্ষেপ করা হয়েছিল:

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]
        ...

নিম্নলিখিত দুটি লগ বার্তাগুলি মূলত উল্লেখযোগ্য যে কোনও ব্যবহারকারীর সেটিংসটি Principalকাজ করে না বা এটি ওভাররাইট করা হয়েছিল তা নির্দেশ করে প্রমাণীকরণ করা হয়নি।

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

আপনার কোম্পানির নাম, eu.ubicon, আপনার আমদানিতে প্রদর্শিত হবে। এটি কি সুরক্ষা ঝুঁকি নয়?
কাইল ব্রিজেনস্টাইন

2
হাই, মন্তব্যের জন্য ধন্যবাদ! যদিও দেখতে পাচ্ছি না। এটি যাইহোক ওপেন সোর্স সফ্টওয়্যার। আপনি যদি আগ্রহী হন তবে বিটবুককেট.আর.উউবিকন / ইউবিকন (অথবা বিটবুকકેટ.আর.ডিমার_উইউ / সর্বশেষ কাঁটাচামড়ার জন্য) দেখুন। আমি যদি কিছু মিস করি তবে আমাকে জানান।
মার্টিন বেকার

এই সমাধানটি পরীক্ষা করে দেখুন (উত্তরটি বসন্ত 4 এর জন্য): stackoverflow.com/questions/14308341/…
নাগি আটিলা

উত্তর:


101

উত্তরের সন্ধানে আমি একইসাথে কোনও সহজ এবং নমনীয় হতে পারলাম না, তারপরে আমি স্প্রিং সিকিউরিটি রেফারেন্সটি পেয়েছি এবং বুঝতে পেরেছি নিখুঁত সমাধানের নিকটেই রয়েছে are Aop সমাধান প্রায়ই পরীক্ষার জন্য সর্বাধিক বেশী, এবং স্প্রিং সঙ্গে এটি উপলব্ধ করা @WithMockUser, @WithUserDetailsএবং @WithSecurityContextএই হস্তনির্মিত বস্তু মধ্যে:

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

বেশিরভাগ ক্ষেত্রে, @WithUserDetailsআমার প্রয়োজনীয় নমনীয়তা এবং শক্তি সংগ্রহ করে।

কিভাবে @WithUserDetails কাজ করে?

মূলত আপনাকে UserDetailsServiceপরীক্ষা করতে চান এমন সমস্ত সম্ভাব্য ব্যবহারকারীর প্রোফাইলের সাথে একটি কাস্টম তৈরি করতে হবে। যেমন

@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
        ));
    }
}

এখন আমরা আমাদের ব্যবহারকারীদের প্রস্তুত, তাই আমরা এই নিয়ন্ত্রণকারী ফাংশন অ্যাক্সেস নিয়ন্ত্রণ পরীক্ষা করতে চান কল্পনা:

@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());
    }
}

এখানে আমরা একটি আছে পেতে ম্যাপ ফাংশন রুট / foo বিন্যাস / স্যালুট এবং আমরা সঙ্গে একটি ভূমিকা ভিত্তিক নিরাপত্তা পরীক্ষা @Secured, টীকা, যদিও আপনি পরীক্ষা করতে পারেন @PreAuthorizeএবং @PostAuthorizeহিসাবে ভাল। আসুন দুটি পরীক্ষা তৈরি করুন, একটি বৈধ ব্যবহারকারী এই স্যালুট প্রতিক্রিয়া দেখতে পাবে কিনা তা পরীক্ষা করা এবং অন্যটি এটি নিষিদ্ধ কিনা তা পরীক্ষা করতে।

@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());
    }
}

আপনি দেখতে পান যে আমরা SpringSecurityWebAuxTestConfigআমাদের ব্যবহারকারীদের পরীক্ষার জন্য সরবরাহ করতে আমদানি করেছি । প্রত্যেকে কেবলমাত্র সরল টীকা ব্যবহার করে কোড এবং জটিলতা হ্রাস করে এর সাথে সম্পর্কিত পরীক্ষার ক্ষেত্রে ব্যবহৃত হয়।

সরল ভূমিকা ভিত্তিক সুরক্ষার জন্য @WithMockUser ব্যবহার করে আরও ভাল ব্যবহার

আপনি দেখতে যেমন আপনার @WithUserDetailsবেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য প্রয়োজনীয় সমস্ত নমনীয়তা রয়েছে। এটি আপনাকে কোনও গ্রান্টডঅটিরিটি সহ কাস্টম ব্যবহারকারীদের যেমন ভূমিকা বা অনুমতিগুলির ব্যবহার করতে দেয়। তবে আপনি যদি কেবল ভূমিকা নিয়ে কাজ করছেন তবে পরীক্ষা করা আরও সহজ হতে পারে এবং আপনি কোনও কাস্টম তৈরি করা এড়াতে পারেন UserDetailsService। এই ক্ষেত্রে, ব্যবহারকারী, পাসওয়ার্ড এবং সঙ্গে ভূমিকা একটি সহজ সমন্বয় উল্লেখ @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";
}

টীকাগুলি একটি খুব বেসিক ব্যবহারকারীর জন্য ডিফল্ট মান নির্ধারণ করে। আমাদের ক্ষেত্রে যেমন আমরা যে রুটটি পরীক্ষা করছি কেবল তার জন্য প্রমাণীকৃত ব্যবহারকারী একজন পরিচালক হতে হবে, আমরা এটি ব্যবহার বন্ধ করতে SpringSecurityWebAuxTestConfigএবং এটি করতে পারি।

@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")));
}

লক্ষ্য করুন যে এখন ইউজার ম্যানেজার @ company.com এর পরিবর্তে আমরা ডিফল্টটি প্রদান করছি @WithMockUser: ব্যবহারকারী ; এখনো এটা করবে না ব্যাপার কারণ কি আমরা সত্যিই যত্নশীল তাঁর ভূমিকার হল: ROLE_MANAGER

উপসংহার

আপনি যেমন টীকাগুলির সাথে দেখতে পাচ্ছেন @WithUserDetailsএবং @WithMockUserআমরা কেবল সাধারণ পরীক্ষা করার জন্য আমাদের আর্কিটেকচার থেকে আলাদা ক্লাস তৈরি না করেই বিভিন্ন প্রামাণিক ব্যবহারকারীদের পরিস্থিতিতে পরিবর্তন করতে পারি । এটি আপনাকে @ উইথসিকিউরিটি কনটেক্সট আরও নমনীয়তার জন্য কীভাবে কাজ করে তা দেখার পরামর্শ দেয় ।


একাধিক ব্যবহারকারীকে কীভাবে উপহাস করবেন ? উদাহরণস্বরূপ, প্রথম অনুরোধটি প্রেরণ করা হয় tom, যখন দ্বিতীয়টি হয় jerry?
ch271828n

আপনার পরীক্ষাটি টম সহ যেখানে আপনি একটি ফাংশন তৈরি করতে পারেন এবং একই যুক্তি দিয়ে অন্য পরীক্ষা তৈরি করতে পারেন এবং এটি জেরির সাথে পরীক্ষা করতে পারেন। প্রতিটি পরীক্ষার জন্য একটি নির্দিষ্ট ফলাফল থাকবে তাই বিভিন্ন জোর দেওয়া হবে এবং যদি কোনও পরীক্ষা ব্যর্থ হয় তবে এটি আপনাকে তার নাম দিয়ে জানিয়ে দেবে কোন ব্যবহারকারী / ভূমিকা কাজ করে নি। মনে রাখবেন যে একটি অনুরোধে ব্যবহারকারী কেবল একজনই হতে পারে, তাই কোনও অনুরোধে একাধিক ব্যবহারকারীকে নির্দিষ্ট করা কোনও অর্থবোধ করে না।
এলিউক্স

দুঃখিত, আমি উদাহরণস্বরূপ এমন দৃশ্যের অর্থ করছি: আমরা এটি পরীক্ষা করি, টম একটি গোপন নিবন্ধ তৈরি করে, তারপরে জেরি এটি পড়ার চেষ্টা করে এবং জেরি এটি দেখতে না পারা (যেহেতু এটি গোপন)। সুতরাং এই ক্ষেত্রে এটি এক ইউনিট পরীক্ষা ...
ch271828n

এটি দেখতে বেশ উত্তমরূপে BasicUserএবং Manager Userউত্তরে প্রদত্ত দৃশ্যের মতো । মূল ধারণাটি হ'ল ব্যবহারকারীদের যত্ন নেওয়ার পরিবর্তে আমরা প্রকৃতপক্ষে তাদের ভূমিকা সম্পর্কে যত্নশীল, তবে একই ইউনিট পরীক্ষায় অবস্থিত tests পরীক্ষাগুলির প্রত্যেকটিই আসলে বিভিন্ন প্রশ্নের প্রতিনিধিত্ব করে। বিভিন্ন ব্যবহারকারীর দ্বারা (বিভিন্ন ভূমিকা সহ) একই শেষ পয়েন্টে করা।
এলিউক্স

61

স্প্রিংস 4.0+ থেকে, সেরা সমাধান হ'ল @ উইথমক ইউজারের মাধ্যমে পরীক্ষার পদ্ধতিটি বর্ননা করা

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

আপনার প্রকল্পে নিম্নলিখিত নির্ভরতা যুক্ত মনে রাখবেন

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

1
বসন্ত আশ্চর্যজনক। ধন্যবাদ
টুগোর্ডোবেলো

ভাল উত্তর. তদুপরি - আপনাকে মকএমভিসি ব্যবহার করার দরকার নেই, তবে আপনি যদি স্প্রিংফ্রেমওয়ার্ক.ডাটা থেকে উদাহরণস্বরূপ পেজিংএন্ডসোর্টিংরেপসিটরি ব্যবহার করছেন - আপনি কেবল সংগ্রহস্থল থেকে সরাসরি পদ্ধতিগুলি কল করতে পারেন (যা এলএল @PreAuthorize (......) দ্বারা টীকায়িত হয়)
সুপারট্র্যাম্প

50

দেখা গেল যে SecurityContextPersistenceFilterস্প্রিং সিকিউরিটি ফিল্টার চেইনের অংশ, সর্বদা আমার পুনরায় SecurityContextসেট করে, যা আমি কলিং সেট করেছি SecurityContextHolder.getContext().setAuthentication(principal)(বা .principal(principal)পদ্ধতিটি ব্যবহার করে )। এই ফিল্টার সেট করে SecurityContextSecurityContextHolderএকটি সঙ্গে SecurityContextএকটি থেকে SecurityContextRepository মুছে যাওয়ার এক আমি আগেও সেট। সংগ্রহস্থলটি HttpSessionSecurityContextRepositoryডিফল্টরূপে। HttpSessionSecurityContextRepositoryপরিদর্শন দেওয়া HttpRequestএবং অ্যাক্সেস করতে চেষ্টা সংশ্লিষ্ট HttpSession। যদি বিদ্যমান, তা পাঠ করার চেষ্টা করবে SecurityContextথেকে HttpSession। এটি ব্যর্থ হলে, সংগ্রহস্থলটি একটি খালি তৈরি করে SecurityContext

সুতরাং, আমার সমাধানটি HttpSessionঅনুরোধটির সাথে একটি পাশ করা, যা হ'ল 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
আমরা এখনও স্প্রিং সিকিউরিটির জন্য সরকারী সমর্থন যোগ করি নি। দেখুন jira.springsource.org/browse/SEC-2015 এটা কিসের মত উল্লেখ করা হয় দেখবে জন্য একটি সীমারেখা github.com/SpringSource/spring-test-mvc/blob/master/src/test/...
রব শক্তিশালী কপিকলবিশেষ

আমি মনে করি না যে কোনও প্রমাণীকরণ অবজেক্ট তৈরি করা এবং সংশ্লিষ্ট বৈশিষ্ট্যের সাথে একটি সেশন যুক্ত করা খারাপ। আপনি কি মনে করেন এটি একটি বৈধ "চারপাশের কাজ"? অন্যদিকে সরাসরি সমর্থন অবশ্যই দুর্দান্ত হবে। দেখতে বেশ ঝরঝরে। লিঙ্কের জন্য ধন্যবাদ!
মার্টিন বেকার 1

দুর্দান্ত সমাধান আমার জন্য কাজ! সুরক্ষিত পদ্ধতির নামকরণের সাথে একটি সামান্য সমস্যা getPrincipal()যা আমার মতে কিছুটা বিভ্রান্তিকর। আদর্শভাবে এটি নামকরণ করা উচিত ছিল getAuthentication()। তেমনিভাবে, আপনার signedIn()পরীক্ষায়, স্থানীয় ভেরিয়েবলের নাম দেওয়া উচিত authবা authenticationতার পরিবর্তেprincipal
তানভীর

"গেটপ্রিন্টিকাল (" টেস্ট 1 ") কী? ¿?? আপনি কোথায় তা ব্যাখ্যা করতে পারবেন যে এটি কোথায়? আগাম ধন্যবাদ
ব্যবহারকারী 2992476

@ user2992476 এটি সম্ভবত ব্যবহারকারীর নামপ্যাসওয়ার্ডআউটেনটিকেশন টোকেন টাইপের একটি অবজেক্ট দেয়। বিকল্পভাবে, আপনি GrantedAuthority তৈরি করেন এবং এই অবজেক্টটি তৈরি করেন।
bluelurker

31

Pom.xML এ যুক্ত করুন:

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

এবং org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessorsঅনুমোদনের অনুরোধের জন্য ব্যবহার করুন । Https://github.com/rwinch/spring-security-test-blog এ নমুনা ব্যবহার দেখুন ( https://jira.spring.io/browse/SEC-2592 ) ।

হালনাগাদ:

4.0.0.RC2 বসন্ত-সুরক্ষা 3.x এর জন্য কাজ করে। বসন্ত-সুরক্ষার জন্য 4 বসন্ত-সুরক্ষা-পরীক্ষা বসন্ত-সুরক্ষার অংশ হয়ে যায় ( http://docs.spring.io/spring-security/site/docs/4.0.x/references/htmlsingle/#test , সংস্করণ একই )।

সেট আপটি পরিবর্তন করা হয়েছে: http://docs.spring.io/spring-security/site/docs/4.0.x/references/htmlsingle/#test-mockmvc

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

বেসিক-প্রমাণীকরণের জন্য নমুনা: http://docs.spring.io/spring-security/site/docs/4.0.x/references/htmlsingle/#testing-http-basic-authentication


এটি লগইন সুরক্ষা ফিল্টারটির মাধ্যমে লগইন করার চেষ্টা করার সময় 404 পাওয়ার সাথে আমার সমস্যাটিও স্থির করে। ধন্যবাদ!
ইয়ান নিউল্যান্ড

হাই, জি কিসলিন দ্বারা উল্লিখিত হিসাবে পরীক্ষা করার সময়। আমি নিম্নলিখিত ত্রুটি পেয়ে যাচ্ছি "প্রমাণীকরণ ব্যর্থ হয়েছে ইউজারডেটেলস সার্ভিস নাল, যা একটি ইন্টারফেস চুক্তি লঙ্ঘন"। কোন পরামর্শ দয়া করে। চূড়ান্ত প্রমাণীকরণের অনুরোধ auth = new AuthenticationRequest (); auth.setUsername (আইডি); auth.setPassword (পাসওয়ার্ড); mockMvc.perform (।। পোস্ট ( "/ API / প্রমাণীকরণ /") বিষয়বস্তু (JSON (প্রমাণীকরণ)) contentType (MediaType.APPLICATION_JSON));
সঞ্জীব

7

যারা বেস 64 মৌলিক প্রমাণীকরণ ব্যবহার করে স্প্রিং মকএমভিসি সুরক্ষা কনফিগারেশন পরীক্ষা করতে চান তাদের উদাহরণ এখানে।

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());

মাভেন নির্ভরতা

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

3

সংক্ষিপ্ত উত্তর:

@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;
}

formLoginবসন্ত সুরক্ষা পরীক্ষা থেকে সম্পাদনের পরে আপনার প্রতিটি অনুরোধ স্বয়ংক্রিয়ভাবে লগ ইন করা ব্যবহারকারী হিসাবে কল করা হবে।

দীর্ঘ উত্তর:

এই সমাধানটি পরীক্ষা করে দেখুন (উত্তরটি বসন্ত 4 এর জন্য): কীভাবে কোনও ব্যবহারকারীকে বসন্ত 3.2 নতুন এমভিসি পরীক্ষার মাধ্যমে লগইন করতে পারেন


2

পরীক্ষায় সিকিউরিটি কনটেক্সটহোল্ডার ব্যবহার এড়াতে বিকল্পগুলি:

  • বিকল্প 1 : মক SecurityContextHolderব্যবহার করুন - মানে কিছু মোক উপগ্রহ গ্রন্থাগার ব্যবহার করে - উদাহরণস্বরূপ EasyMock
  • বিকল্প 2 : SecurityContextHolder.get...কিছু কোডে আপনার কোডটিতে কলটি মোড়ক করুন - উদাহরণস্বরূপ SecurityServiceImplএমন পদ্ধতিতে getCurrentPrincipalযা SecurityServiceইন্টারফেস প্রয়োগ করে এবং তারপরে আপনার পরীক্ষাগুলিতে আপনি কেবল এই ইন্টারফেসের মক বাস্তবায়ন তৈরি করতে পারেন যা অ্যাক্সেস ছাড়াই পছন্দসই অধ্যক্ষকে ফিরিয়ে দেয় SecurityContextHolder

মিঃ, সম্ভবত আমি পুরো ছবিটি পাই না। আমার সমস্যাটি ছিল যে সিকিউরিটি কনটেক্সট পার্সনিস্টি ফিল্টারটি একটি এইচটিপিএসশনসিকিউরিটি কনটেক্সট রিপোসিটরি থেকে সিকিউরিটি কনটেক্সট ব্যবহার করে সিকিউরিটি কনটেক্সটকে প্রতিস্থাপন করে, যা পরিবর্তিত সুরক্ষা কনটেক্সটটি সম্পর্কিত এইচটিটিপিএসশন থেকে পড়ে। এইভাবে সেশনটি ব্যবহার করে সমাধান করুন। সিকিউরিটি কনটেক্সটহোল্ডারকে কল সম্পর্কিত: আমি আমার উত্তরটি সম্পাদনা করেছি যাতে আমি আর সুরক্ষাকন্টেক্সটহোল্ডারে কোনও কল ব্যবহার করি না। তবে কোনও মোড়ানো বা অতিরিক্ত উপহাসের পাঠাগারগুলি চালু না করেই আপনি কি মনে করেন, এটি আরও ভাল সমাধান?
মার্টিন বেকার 1

দুঃখিত আপনি ঠিক কী খুঁজছেন তা আমি বুঝতে পারি নি এবং আপনি যে সমাধানটি নিয়ে এসেছেন তার চেয়ে ভাল উত্তর দিতে পারছি না এবং - এটি একটি ভাল বিকল্প বলে মনে হয়।
পাভলা নোভকোভাক

ঠিক আছে, ধন্যবাদ. আমি আপাতত সমাধান হিসাবে আমার প্রস্তাব গ্রহণ করব।
মার্টিন বেকার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.