Spring Boot ã§JDBCã使ã£ã¦ã¦ã¼ã¶ã¼ç»é²ã»ã¦ã¼ã¶ã¼èªè¨¼ããæ¹æ³
ã¾ãã¯å ¬å¼ã«å¾ãã
â« https://spring.io/guides/gs/securing-web/
pom.xmlã«jpaã¨securityã追å ã
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
DBã¯ãHSQLDBã使ç¨ã
appliaction.properties ã¯ä»¥ä¸ã®éãã
spring.datasource.url=jdbc:hsqldb:hsql://localhost/auth spring.datasource.username=sa spring.datasource.password= spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.jpa.hibernate.ddl-auto=update
ããããã¼ã¸ã(index.html)ãä½æã
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ããããã¼ã¸</title> </head> <body> <h1>ããããã¼ã¸</h1> <a href="/mypage">ãã¤ãã¼ã¸</a> </body> </html>
èªè¨¼ãå¿ è¦ãªãã¼ã¸(mypage.html)ãä½æã
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>login</title> </head> <body> <h1>ãã¤ãã¼ã¸</h1> <form th:action="@{/logout}" method="post"> <input type="submit" value="ãã°ã¢ã¦ã" /> </form> </body> </html>
ãã°ã¤ã³ç»é¢(login.html)ãä½æã
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>login</title> </head> <body> <div th:if="${param.error}"> ã¨ã©ã¼: ã¦ã¼ã¶åã»ãã¹ã¯ã¼ããéãã¾ãã </div> <form th:action="@{/login}" method="post"> <div><label>ã¦ã¼ã¶å: <input type="text" name="username"/> </label></div> <div><label>ãã¹ã¯ã¼ã: <input type="password" name="password"/> </label></div> <div><input type="submit" value="ãã°ã¤ã³"/></div> </form> <div><a href="/newuser">æ°è¦ã¦ã¼ã¶ã¼ç»é²</a></div> <a href="/">æ»ã</a> </body> </html>
æ°è¦ã¦ã¼ã¶ã¼ç»é²ç»é¢(newuser.html)ãä½æã
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>æ°è¦ã¦ã¼ã¶ã¼ç»é²</title> </head> <body> <h1>æ°è¦ã¦ã¼ã¶ã¼ç»é²</h1> <form th:action="@{/newuser}" method="post"> <div><label>ã¦ã¼ã¶å: <input type="text" name="username"/> </label></div> <div><label>ãã¹ã¯ã¼ã: <input type="password" name="password"/> </label></div> <div><label>ãã¹ã¯ã¼ãåå ¥å: <input type="password" name="password2"/> </label></div> <div><input type="submit" value="ç»é²"/></div> </form> <a href="/">æ»ã</a> </body> </html>
ã³ã³ããã¼ã©ãä½æã
package hoge; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class MyController { @RequestMapping(value = "/") public String index() { return "index"; } @RequestMapping(value = "/login") public String login() { return "login"; } @RequestMapping(value = "/newuser") public String newuser() { return "newuser"; } @RequestMapping(value = "/mypage") public String top() { return "mypage"; } }
ãã®ç¶æ ã§Spring Bootã¢ããªãèµ·åããã¨ãèªè¨¼ã®å¶éãããã£ã¦ãªãã®ã§ãåãã¼ã¸ãèªç±ã«è¡ãæ¥ã§ããã
/ 㨠/newuser ã¯èª°ã§ãã¢ã¯ã»ã¹å¯è½ã
/mypage ã¯ããã°ã¤ã³ããªãã¨ã¢ã¯ã»ã¹ã§ããªãããã«ããã
package hoge; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/newuser").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); }
ä¸è¨ã®WebSecurityConfig ãä½ã£ã¦ããåèµ·åããã¨ã/ 㨠/newuser ã«ã¯ã¢ã¯ã»ã¹å¯è½ã/mypage ã«ã¢ã¯ã»ã¹ãããã¨ããã¨ã/login ã«é£ã°ãããã
JDBCã§èªè¨¼ã§ããããã«ããã
å ¬å¼ã«ã¯ã¡ãã£ã¨JDBCèªè¨¼ã®æ¹æ³ãããã
â« https://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html
@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { UserBuilder users = User.withDefaultPasswordEncoder(); auth .jdbcAuthentication() .dataSource(dataSource) .withDefaultSchema() .withUser(users.username("user").password("password").roles("USER")); }
ãããããã®ã³ã¼ãã ã¨ä¸çºç®ã¯åä½ãããã©ãäºåç®ããã¯ä¾å¤ãçºçãã¦Spring Boot ã¢ããªãèµ·åããªããªãã
withDefaultSchema()ã¨withUser()ããããä¾å¤ã®åå ã ã£ãã
以ä¸ã®1è¡ã ãã«ããã°äºåç®ãããåé¡ãªãåä½ããã
@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication().dataSource(dataSource); }
ãã®å
ã®å®è£
æ¹æ³ãããããªãã¦ããããããã£ã¦ã¿ãã
ããå
¬å¼ã®ããã¥ã¡ã³ããå°ãªãããããã£ã¦ã¿ã¦ãå²ã¨è¤éãªã³ã¼ãã§å®è£
ãã¦ã人ãå¤ãã¦å°ã£ãã
ãªãã¨ãªãããã£ã¨ç°¡åãªã³ã¼ãã§å®è£ ã§ããããªæ°ãããã¨æã£ãã®ã§é©å½ã«ã³ã¼ãæ¸ãããåãã¡ãã£ãã
æ°è¦ã¦ã¼ã¶ã¼ç»é²ã§ããããã«ããã
ã¨ããããJdbcUserDetailsManager ãã³ã³ããã¼ã©ã«DIãã¦ã¿ãã
@Autowired private JdbcUserDetailsManager userManager;
/newuser ã® POST ã§ã¦ã¼ã¶ã¼ç»é²ããå¦çãæ¸ãã
JdbcUserDetailsManagerã«createUser()ã¨ããã¡ã½ããããã£ãã®ã§ããã使ãã°ã§ããããããªãããªã¨ã
ä¸è¨ã®å
¬å¼ã®èª¬æã§InMemoryUserDetailsManagerã§ããããã¦ããã
ã¹ã¼ãã¼ã¯ã©ã¹ãåãã ãããã¶ããããã¯ãï¼
@RequestMapping(value = "/newuser", method = RequestMethod.GET) public String newuser() { return "newuser"; } @RequestMapping(value = "/newuser", method = RequestMethod.POST) public String register(@RequestParam("username") String username, @RequestParam("password") String password) { UserBuilder users = User.withDefaultPasswordEncoder(); userManager.createUser(users.username(username).password(password).roles("USER").build()); return "login"; }
User.withDefaultPasswordEncoder()ã§deprecatedã®è¦åãåºãã®ã§ãæ°ã«ãªã人ã¯é©å½ãªPasswordEncoderãè¨å®ãã¦ãã
ããã§èµ·åãããã¨ããããJdbcUserDetailsManagerãDIããããã©ãå®ç¾©ããªãããã§ããªããã£ã¦æãããã
JdbcUserDetailsManager 㨠DataSource ãWebSecurityConfigã«ç¨æããã
ãããããããã©ãã¤ã³ã¹ã¿ã³ã¹çæãã¦DataSourceã ãè¨å®ãã¨ãã°åãããããï¼çãªã
@Autowired private DataSource dataSource; @Bean public JdbcUserDetailsManager jdbcUserDetailsManager() throws Exception { JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(); jdbcUserDetailsManager.setDataSource(dataSource); return jdbcUserDetailsManager; }
åé¡ãªãèµ·åã§ããã
ã§ããDBã«ã¦ã¼ã¶ã¼ãåå¨ããªãã®ã§ãã°ã¤ã³ã§ããªãã
/newuser ããæ°è¦ã¦ã¼ã¶ã¼ç»é²ããã
æ°è¦ã¦ã¼ã¶ã¼ç»é²å¾ã¯ãUSERSãã¼ãã«ã«ç»é²ããã¦ããã®ã確èªã§ããããã¹ã¯ã¼ããæå·åããã¦ãã
ã¨ããããã§ãã¦ã¼ã¶ã¼ç»é²ã¯æåã
ç»é²ããã¦ã¼ã¶ã¼ã§ãã°ã¤ã³ããã¨ã/mypage ã«è¡ããããã«ãªã£ãã
ã¦ã¼ã¶ã¼èªè¨¼ãæåã
ç»é²æ¸ã¿ã®ã¦ã¼ã¶ã¼åã§åã³ç»é²ãããã¨ããã¨ä¾å¤ãçºçããã
ãã®ã¨ã©ã¼ãã³ããªã³ã°ã¨ããã¹ã¯ã¼ãåå
¥åã®ãã§ãã¯ã追å ããã
@RequestMapping(value = "/newuser", method = RequestMethod.POST) public ModelAndView register( ModelAndView mav, @RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("password2") String password2) { if (!password.equals(password2)) { mav.setViewName("newuser"); mav.addObject("error", "ãã¹ã¯ã¼ããä¸è´ãã¦ãã¾ããã"); return mav; } UserBuilder users = User.withDefaultPasswordEncoder(); try { userManager.createUser(users.username(username).password(password).roles("USER").build()); mav.setViewName("login"); } catch (Exception e) { mav.setViewName("newuser"); mav.addObject("error", "ã¦ã¼ã¶ã¼åã¯ä½¿ç¨ã§ãã¾ããã:" + username); } return mav; }
ããã§JDBCã使ç¨ããã¦ã¼ã¶ã¼ç»é²ã¨ã¦ã¼ã¶ã¼èªè¨¼ã®åä½ãã§ããããã«ãªã£ãã
WebSecurityConfig ã®å ¨ä½ã
package hoge; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.provisioning.JdbcUserDetailsManager; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Autowired private DataSource dataSource; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/newuser").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication() .dataSource(dataSource); } @Bean public JdbcUserDetailsManager jdbcUserDetailsManager() throws Exception { JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(); jdbcUserDetailsManager.setDataSource(dataSource); return jdbcUserDetailsManager; } }
ã³ã³ããã¼ã©ã®å ¨ä½ã
package hoge; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User.UserBuilder; import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @Controller public class MyController { @Autowired private JdbcUserDetailsManager userManager; @RequestMapping(value = "/") public String index() { return "index"; } @RequestMapping(value = "/login") public String login() { return "login"; } @RequestMapping(value = "/newuser", method = RequestMethod.GET) public String newuser() { return "newuser"; } @RequestMapping(value = "/newuser", method = RequestMethod.POST) public ModelAndView register( ModelAndView mav, @RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("password2") String password2) { if (!password.equals(password2)) { mav.setViewName("newuser"); mav.addObject("error", "ãã¹ã¯ã¼ããä¸è´ãã¦ãã¾ããã"); return mav; } UserBuilder users = User.withDefaultPasswordEncoder(); try { userManager.createUser(users.username(username).password(password).roles("USER").build()); mav.setViewName("login"); } catch (Exception e) { mav.setViewName("newuser"); mav.addObject("error", "ã¦ã¼ã¶ã¼åã¯ä½¿ç¨ã§ãã¾ããã:" + username); } return mav; } @RequestMapping(value = "/mypage") public String mypage() { return "mypage"; } }