\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0(Spring Security)\ub294 \uc2a4\ud504\ub9c1 \ud504\ub808\uc784\uc6cc\ud06c\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ubcf4\uc548 \ud504\ub808\uc784\uc6cc\ud06c\ub85c, \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubcf4\uc548\uc744 \ucc98\ub9ac\ud558\ub294 \uae30\ub2a5\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \uc778\uc99d\uacfc \uad8c\ud55c \ubd80\uc5ec\ub97c \ucc98\ub9ac\ud558\uba70, \uac04\ub2e8\ud55c \uc124\uc815\uacfc \ud568\uaed8 \uc190\uc27d\uac8c \ubcf4\uc548 \uae30\ub2a5\uc744 \uad6c\ud604\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \ub2e4\uc591\ud55c \uc778\uc99d \ubc29\uc2dd\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4. \uae30\ubcf8\uc801\uc73c\ub85c\ub294 \ud3fc \uae30\ubc18 \uc778\uc99d\uc744 \uc0ac\uc6a9\ud558\uba70, HTTP \uae30\ubcf8 \uc778\uc99d, OAuth 2.0, OpenID Connect \ub4f1\uacfc \uac19\uc740 \ub2e4\uc591\ud55c \uc778\uc99d \ubc29\uc2dd\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4. \ub610\ud55c, \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \uc138\uc158 \uad00\ub9ac\uc640 CSRF(Cross-Site Request Forgery) \uacf5\uaca9 \ubc29\uc5b4 \ub4f1\uc758 \ubcf4\uc548 \uae30\ub2a5\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4.<\/p>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \uc2a4\ud504\ub9c1 \ud504\ub808\uc784\uc6cc\ud06c\uc640 \ud568\uaed8 \uc0ac\uc6a9\ud558\uae30 \uc27d\uc2b5\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \uc0ac\uc6a9\ud558\uba74 \ubcf4\uc548\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc804\uc801\uc73c\ub85c \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\uac00 \ucc98\ub9ac\ud574\uc8fc\uae30 \ub54c\ubb38\uc5d0 \uac1c\ubc1c\uc790\ub294 \ubcf4\uc548\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc2e0\uacbd\uc4f0\uc9c0 \uc54a\uace0 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \ud65c\uc6a9\ud558\uc5ec \uc548\uc804\ud55c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \ubc29\ubc95\uc744 \uc54c\uc544\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \uc124\uc815\ud574\uc57c \ud569\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0 \uc124\uc815\uc740 XML \ud30c\uc77c\uc774\ub098 Java Config \ud30c\uc77c\uc744 \uc774\uc6a9\ud558\uc5ec \ucc98\ub9ac\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n
XML \ud30c\uc77c\uc744 \uc774\uc6a9\ud55c \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0 \uc124\uc815 \uc608\uc2dc\uc785\ub2c8\ub2e4. <\/p>\n
<\/code><\/pre>\nJava Config\uc744 \uc774\uc6a9\ud55c \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0 \uc124\uc815 \uc608\uc2dc\uc785\ub2c8\ub2e4.<\/p>\n
@Configuration\n@EnableWebSecurity\npublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {\n\n @Override\n protected void configure(HttpSecurity http) throws Exception {\n http\n .authorizeRequests()\n .antMatchers(\"\/admin\/**\").hasRole(\"ADMIN\")\n .anyRequest().authenticated()\n .and()\n .formLogin()\n .loginPage(\"\/login\")\n .failureUrl(\"\/login?error=true\")\n .and()\n .logout()\n .logoutSuccessUrl(\"\/\");\n }\n\n @Autowired\n public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {\n auth\n .inMemoryAuthentication()\n .withUser(\"admin\").password(\"admin\").roles(\"ADMIN\");\n }\n}<\/code><\/pre>\n\uc778\uc99d\uacfc \uad8c\ud55c \ubd80\uc5ec<\/h3>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \uc778\uc99d\uacfc \uad8c\ud55c \ubd80\uc5ec\ub97c \ucc98\ub9ac\ud569\ub2c8\ub2e4. \uc778\uc99d\uc740 \uc0ac\uc6a9\uc790\uac00 \uc785\ub825\ud55c \uc815\ubcf4\uac00 \uc62c\ubc14\ub978\uc9c0 \uac80\uc99d\ud558\ub294 \uacfc\uc815\uc744 \ub9d0\ud558\uba70, \uad8c\ud55c \ubd80\uc5ec\ub294 \uc778\uc99d\ub41c \uc0ac\uc6a9\uc790\uac00 \ud2b9\uc815 \ub9ac\uc18c\uc2a4\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc774 \uc788\ub294\uc9c0 \uac80\uc0ac\ud558\ub294 \uacfc\uc815\uc744 \ub9d0\ud569\ub2c8\ub2e4.<\/p>\n
\uc778\uc99d\uacfc \uad8c\ud55c \ubd80\uc5ec\ub97c \uc704\ud574\uc11c\ub294 AuthenticationProvider \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc791\uc131\ud574\uc57c \ud569\ub2c8\ub2e4.<\/p>\n
@Component\npublic class CustomAuthenticationProvider implements AuthenticationProvider {\n\n @Override\n public Authentication authenticate(Authentication authentication) throws AuthenticationException {\n String username = authentication.getName();\n String password = authentication.getCredentials().toString();\n\n \/\/ \uc0ac\uc6a9\uc790 \uc778\uc99d \ucc98\ub9ac\n\n List authorities = new ArrayList();\n authorities.add(new SimpleGrantedAuthority(\"ROLE_USER\"));\n\n return new UsernamePasswordAuthenticationToken(username, password, authorities);\n }\n\n @Override\n public boolean supports(Class authentication) {\n return authentication.equals(UsernamePasswordAuthenticationToken.class);\n }\n}<\/code><\/pre>\n\uc138\uc158 \uad00\ub9ac<\/h3>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \uc138\uc158 \uad00\ub9ac \uae30\ub2a5\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4. \uc138\uc158 \uad00\ub9ac \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uba74 \uc0ac\uc6a9\uc790\uc758 \uc138\uc158 \uc0c1\ud0dc\ub97c \ud655\uc778\ud558\uace0, \uc0ac\uc6a9\uc790\uac00 \ub85c\uadf8\uc544\uc6c3\ud558\uac70\ub098 \uc138\uc158\uc774 \ub9cc\ub8cc\ub418\uc5c8\uc744 \ub54c \ucc98\ub9ac\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\uc758 \uc138\uc158 \uad00\ub9ac \uae30\ub2a5\uc740 HttpSessionEventPublisher\ub97c \ub4f1\ub85d\ud558\ub294 \uac83\uc73c\ub85c \uc2dc\uc791\ud569\ub2c8\ub2e4.<\/p>\n
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {\n\n @Override\n protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {\n servletContext.addListener(new HttpSessionEventPublisher());\n }\n\n}<\/code><\/pre>\n\uc774\ud6c4 \uc138\uc158 \uad00\ub9ac\ub97c \uc704\ud55c \uc124\uc815\uc744 \ucd94\uac00\ud574\uc8fc\uc5b4\uc57c \ud569\ub2c8\ub2e4.<\/p>\n
@Configuration\n@EnableWebSecurity\npublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {\n\n @Override\n protected void configure(HttpSecurity http) throws Exception {\n http\n .sessionManagement()\n .maximumSessions(1)\n .maxSessionsPreventsLogin(true)\n .expiredUrl(\"\/sessionExpired\")\n .sessionRegistry(sessionRegistry());\n }\n\n @Bean\n public SessionRegistry sessionRegistry() {\n return new SessionRegistryImpl();\n }\n\n}<\/code><\/pre>\nCSRF \uacf5\uaca9 \ubc29\uc5b4<\/h3>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 CSRF(Cross-Site Request Forgery) \uacf5\uaca9 \ubc29\uc5b4 \uae30\ub2a5\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4. CSRF \uacf5\uaca9\uc740 \uc0ac\uc6a9\uc790\uc758 \uad8c\ud55c\uc744 \ub3c4\uc6a9\ud558\uc5ec \uc545\uc758\uc801\uc778 \uc694\uccad\uc744 \ubcf4\ub0b4\ub294 \uacf5\uaca9 \ubc29\uc2dd\uc785\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 CSRF \uacf5\uaca9 \ubc29\uc5b4\ub97c \uc704\ud574 CSRF \ud1a0\ud070\uc744 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n
<\/code><\/pre>\n\ubcf4\uc548 \ub85c\uadf8<\/h3>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \ubcf4\uc548 \ub85c\uadf8\ub97c \uae30\ub85d\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ubcf4\uc548 \ub85c\uadf8\ub97c \uae30\ub85d\ud558\uba74 \uc2dc\uc2a4\ud15c\uc5d0 \ub300\ud55c \ubcf4\uc548 \ubb38\uc81c\ub97c \uc2e0\uc18d\ud558\uac8c \ud30c\uc545\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n
<\/code><\/pre>\n\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \uc0ac\uc6a9\ud558\uc5ec \ubcf4\uc548 \ucde8\uc57d\uc810 \ubc29\uc9c0\ud558\uae30<\/h2>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \uc0ac\uc6a9\ud558\uc5ec \ubcf4\uc548 \ucde8\uc57d\uc810\uc744 \ubc29\uc9c0\ud558\ub294 \ubc29\ubc95\uc744 \uc54c\uc544\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n
SQL Injection \ubc29\uc5b4<\/h3>\n
SQL Injection\uc740 \uc0ac\uc6a9\uc790\uac00 \uc785\ub825\ud55c \uac12\uc744 \uc774\uc6a9\ud558\uc5ec SQL \ucffc\ub9ac\ub97c \uc870\uc791\ud558\ub294 \uacf5\uaca9\uc785\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 Prepared Statement\ub97c \uc0ac\uc6a9\ud558\uc5ec SQL Injection \uacf5\uaca9\uc744 \ubc29\uc5b4\ud569\ub2c8\ub2e4.<\/p>\n
String query = \"SELECT * FROM users WHERE username = ? AND password = ?\";\nPreparedStatement pstmt = connection.prepareStatement(query);\npstmt.setString(1, username);\npstmt.setString(2, password);\nResultSet rs = pstmt.executeQuery();<\/code><\/pre>\nXSS \ubc29\uc5b4<\/h3>\n
XSS(Cross-Site Scripting)\ub294 \uc0ac\uc6a9\uc790\uac00 \uc785\ub825\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc545\uc758\uc801\uc73c\ub85c \uc2e4\ud589\ud558\ub294 \uacf5\uaca9\uc785\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 HTML Escape\ub97c \ud1b5\ud574 XSS \uacf5\uaca9\uc744 \ubc29\uc5b4\ud569\ub2c8\ub2e4.<\/p>\n
<\/code><\/pre>\n\ud30c\uc77c \uc5c5\ub85c\ub4dc \ubc29\uc5b4<\/h3>\n
\ud30c\uc77c \uc5c5\ub85c\ub4dc\ub294 \ubcf4\uc548 \ucde8\uc57d\uc810\uc744 \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \ud30c\uc77c \uc5c5\ub85c\ub4dc \uacfc\uc815\uc5d0\uc11c \ud30c\uc77c \ud655\uc7a5\uc790\ub97c \uac80\uc99d\ud558\uace0, \ud30c\uc77c \ud06c\uae30\ub97c \uc81c\ud55c\ud558\uc5ec \ud30c\uc77c \uc5c5\ub85c\ub4dc \uacf5\uaca9\uc744 \ubc29\uc5b4\ud569\ub2c8\ub2e4.<\/p>\n
@Configuration\n@EnableWebSecurity\npublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {\n\n @Override\n protected void configure(HttpSecurity http) throws Exception {\n http\n .csrf().disable()\n .authorizeRequests()\n .antMatchers(\"\/upload\").permitAll()\n .anyRequest().authenticated()\n .and()\n .multipartConfig()\n .fileSizeThreshold(1024 * 1024)\n .maxFileSize(1024 * 1024 * 10)\n .maxRequestSize(1024 * 1024 * 50);\n }\n\n}<\/code><\/pre>\n\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \ud65c\uc6a9\ud55c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubcf4\uc548 \uac15\ud654\ud558\uae30<\/h2>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \ud65c\uc6a9\ud558\uc5ec \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubcf4\uc548\uc744 \uac15\ud654\ud558\ub294 \ubc29\ubc95\uc744 \uc54c\uc544\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n
HTTPS \uc0ac\uc6a9<\/h3>\n
HTTPS\ub97c \uc0ac\uc6a9\ud558\uba74 \uc554\ud638\ud654\ub41c \ud1b5\uc2e0\uc744 \ud560 \uc218 \uc788\uc5b4\uc11c \uc911\uac04\uc790 \uacf5\uaca9\uc744 \ubc29\uc9c0\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 HTTPS\ub97c \uc0ac\uc6a9\ud558\uae30 \uc704\ud55c \uc124\uc815\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4.<\/p>\n
@Configuration\n@EnableWebSecurity\npublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {\n\n @Override\n protected void configure(HttpSecurity http) throws Exception {\n http\n .requiresChannel()\n .anyRequest().requiresSecure()\n .and()\n \/\/ ...\n }\n\n}<\/code><\/pre>\n\ubcf4\uc548 \ud5e4\ub354 \ucd94\uac00<\/h3>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \ubcf4\uc548 \ud5e4\ub354\ub97c \ucd94\uac00\ud558\uc5ec \ubcf4\uc548\uc744 \uac15\ud654\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ubcf4\uc548 \ud5e4\ub354\ub97c \ucd94\uac00\ud558\uba74 XSS, Clickjacking, MIME \uc2a4\ub2c8\ud551 \ub4f1\uacfc \uac19\uc740 \uacf5\uaca9 \ubc29\uc5b4\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.<\/p>\n
@Configuration\n@EnableWebSecurity\npublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {\n\n @Override\n protected void configure(HttpSecurity http) throws Exception {\n http\n .headers()\n .xssProtection()\n .contentTypeOptions()\n .frameOptions()\n .httpStrictTransportSecurity()\n \/\/ ...\n }\n\n}<\/code><\/pre>\n\ubcf4\uc548 \uc774\ubca4\ud2b8 \ucc98\ub9ac<\/h3>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \ubcf4\uc548 \uc774\ubca4\ud2b8\ub97c \ucc98\ub9ac\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ubcf4\uc548 \uc774\ubca4\ud2b8\ub97c \ucc98\ub9ac\ud558\uba74 \uc0ac\uc6a9\uc790 \ub85c\uadf8\uc778 \uc815\ubcf4\uc640 \uac19\uc740 \ubcf4\uc548 \uc815\ubcf4\ub97c \uae30\ub85d\ud558\uace0, \ubcf4\uc548 \uc774\ubca4\ud2b8\uc5d0 \ub300\ud55c \ub300\uc751 \ubc29\uc548\uc744 \uc218\ub9bd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n
@Component\npublic class CustomApplicationListener implements ApplicationListener {\n\n @Override\n public void onApplicationEvent(AbstractAuthenticationEvent event) {\n \/\/ \ubcf4\uc548 \uc774\ubca4\ud2b8 \ucc98\ub9ac\n }\n\n}<\/code><\/pre>\n\ubcf4\uc548 \ud14c\uc2a4\ud2b8<\/h3>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub294 \ubcf4\uc548 \ud14c\uc2a4\ud2b8\ub97c \uc218\ud589\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ubcf4\uc548 \ud14c\uc2a4\ud2b8\ub97c \uc218\ud589\ud558\uba74 \ubcf4\uc548 \ucde8\uc57d\uc810\uc744 \ubc1c\uacac\ud558\uace0, \uc774\ub97c \uc218\uc815\ud558\uc5ec \ubcf4\uc548\uc744 \uac15\ud654\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n
@RunWith(SpringJUnit4ClassRunner.class)\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\npublic class SecurityTest {\n\n @Autowired\n private TestRestTemplate restTemplate;\n\n @Test\n public void test() {\n \/\/ \ubcf4\uc548 \ud14c\uc2a4\ud2b8 \uc218\ud589\n }\n\n}<\/code><\/pre>\n\uacb0\ub860<\/h2>\n
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc548\uc804\ud55c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \ubc29\ubc95\uc744 \uc54c\uc544\ubcf4\uc558\uc2b5\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \uc0ac\uc6a9\ud558\uba74 \ubcf4\uc548 \ucde8\uc57d\uc810\uc744 \ubc29\uc5b4\ud558\uace0, \ubcf4\uc548 \uae30\ub2a5\uc744 \uc190\uc27d\uac8c \uad6c\ud604\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub97c \uc801\uadf9\uc801\uc73c\ub85c \ud65c\uc6a9\ud558\uc5ec \uc548\uc804\ud55c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \uac83\uc744 \uad8c\uc7a5\ud569\ub2c8\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"
\uc2a4\ud504\ub9c1 \uc2dc\ud050\ub9ac\ud2f0\ub85c \uc548\uc804\ud55c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uac1c\ubc1c\ud558\uae30<\/p>\n","protected":false},"author":1,"featured_media":12882,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1957],"tags":[2162,2076,2105,2188,2079,2156,5932],"class_list":["post-36441","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development","tag-event","tag-from","tag-java","tag-public","tag-security","tag-spring","tag-spring-boot"],"acf":[],"_links":{"self":[{"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/posts\/36441","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/comments?post=36441"}],"version-history":[{"count":1,"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/posts\/36441\/revisions"}],"predecessor-version":[{"id":36556,"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/posts\/36441\/revisions\/36556"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/media\/12882"}],"wp:attachment":[{"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/media?parent=36441"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/categories?post=36441"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/m9js.shop\/blog\/wp-json\/wp\/v2\/tags?post=36441"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}