To do unit test with security verification test
Version information
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.14.RELEASE</version> <relativePath/> <!-- lookup parent from repository --></parent><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>1.5.14.RELEASE</version> <!--实际里面spring-security-web的版本是4.2.7--></dependency>
Add dependency
<!--spring-security单元测试--><dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <version>4.2.3.RELEASE</version> <scope>test</scope></dependency><!--spring-security单元测试-->
Demand
- When writing unit tests, you need to impersonate a user's login state
- When writing unit tests, you need to impersonate a user with a certain permission but do not want to change the database
- When writing unit tests, the requirement is to call a user's login completely
Solution Requirements:
Springsecurity provides the relevant component Spring-security-test, which can be consulted in the official documentation (https://docs.spring.io/spring-security/site/docs/5.0.6. release/reference/htmlsingle/#test-method-withmockuser), which provides relevant annotations to impersonate a user's logon information or to invoke a user's login method ,
- @WithMockUser impersonate a user, manually specify the user name and authorization
- @WithAnonymousUser impersonate an anonymous user
- @WithUserDetails impersonated user, given user name, authenticated by custom Userdetails
- @WithSecurityContext impersonate a user through the SecurityContext constructor
For example
@Test@WithMockUser(username="admin",roles={"USER","ADMIN"})public void getMessageWithMockUserCustomUser() { String message = messageService.getMessage(); ...}
Simulated a user named Admin, with the role "user", "admin"
code example
Import Com.alibaba.fastjson.jsonobject;import Org.junit.before;import Org.junit.test;import Org.junit.runner.runwith;import Org.springframework.beans.factory.annotation.autowired;import Org.springframework.boot.test.context.springboottest;import Org.springframework.http.mediatype;import Org.springframework.security.test.context.support.withuserdetails;import Org.springframework.test.annotation.rollback;import Org.springframework.test.context.junit4.springrunner;import Org.springframework.test.web.servlet.mockmvc;import Org.springframework.test.web.servlet.mvcresult;import Org.springframework.test.web.servlet.request.mockmvcrequestbuilders;import Org.springframework.test.web.servlet.setup.mockmvcbuilders;import Org.springframework.transaction.annotation.transactional;import Org.springframework.web.context.webapplicationcontext;import Java.util.hashmap;import java.util.Map;import Static Org.springframework.security.test.web.servlet.request.securitymockmvcrequestbuilders.formlogin;importstatic Org.springframework.security.test.web.servlet.request.securitymockmvcrequestbuilders.logout;import Static Org.springframework.security.test.web.servlet.response.securitymockmvcresultmatchers.authenticated;import Static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated; Import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; Import static Org.springframework.test.web.servlet.result.mockmvcresultmatchers.content;import static org.springframework.test.web.servlet.result.mockmvcresultmatchers.status;/** * Interface Test + springsecurity User Login simulation */@ Runwith (Springrunner.class) @SpringBootTest @transactional@rollback (TRUE)//transaction auto Rollback, default is true. You can not write public class Examplerestclienttest {private MOCKMVC MOCKMVC;//Simulate MVC object, through Mockmvcbuilders.webappcontextsetup (this . WAC). Build () initialization. @Autowired private Webapplicationcontext WAC; Inject Webapplicationcontext @Before//Initialize work public void setup before test starts() {This.mockmvc = Mockmvcbuilders.webappcontextsetup (THIS.WAC). Apply (Springsecurity ()). build (); } @Test @WithUserDetails (value = "admin", Userdetailsservicebeanname = "customuserdetailsservice") public void Te StQ1 () throws Exception {map<string, object> Map = new hashmap<> (); Map.put ("param1", "VALUEAA"); Mvcresult result = Mockmvc.perform (Mockmvcrequestbuilders.post ("/secmenu/getusermenulist"). ContentType (Med IATYPE.APPLICATION_JSON_UTF8). Content (jsonobject.tojsonstring (map)). Andexpect (Status (). is (200))//Analog to test Rest sends a GET request. Andexpect (Content (). ContentType (Mediatype.application_json_utf8))//The media type of the expected return value Text/plain;chars Et=utf-8. Andreturn ()//Returns the result of executing the request} @Test public void Testformloginsuccess () throws Exception { Test the login Success Mockmvc. Perform (Formlogin ("/login"). User ("admin"). Password ("123456")) . Andexpect (Authenticated ()); } @Test public void Testformloginfail () throws Exception {//Test login failed MOCKMVC. Perform (f Ormlogin ("/login"). User ("admin"). Password ("invalid")). Andexpect (unauthenticated ()); } @Test public void Testlogoutfail () throws Exception {//Test exit Login Mockmvc.perform (Logout ("/logout")). A Ndexpect (unauthenticated ()); }}
Complete Project Engineering Reference
Https://github.com/starmoon1994/springsecurity-collection
2539-springsecurity Series-Unit test with safety verification test