如果想在〈DataSource 設置〉的 toy 加上 Spring Security 對每個頁面進行防護呢?這可以在 build.gradle 中加入 Security 的 Starter:
implementation('org.springframework.boot:spring-boot-starter-security')
Spring Boot 只要有 Spring Security 相對應的程式庫存在,就會自動啟用頁面防護,預設的使用者名稱為 user
,密碼為隨機產生,在啟動專案時,可以於日誌訊息中看到:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
2018-12-10 09:04:27.667 INFO 14284 --- [ main]
...略
2018-12-10 09:04:29.153 INFO 14284 --- [ main] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 90a63497-e39c-45b7-a5f8-d916b26fd9f9
當然,你可以自行設置使用者名稱與密碼,這可以在 application.properties 中設定:
spring.security.user.name=caterpillar
spring.security.user.password=12345678
如果想〈套用 jdbcAuthentication〉呢?這就需要寫設定檔了,例如,直接寫在標註了 @SpringBootApplication
的主類別上:
package cc.openhome.toy;
...略
@SpringBootApplication(
scanBasePackages={
"cc.openhome.controller",
"cc.openhome.model"
}
)
public class ToyApplication {
@Bean
public WebSecurityConfigurerAdapter webSecurityConfig(DataSource dataSource) {
return new WebSecurityConfigurerAdapter() {
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.jdbcAuthentication()
.passwordEncoder(new BCryptPasswordEncoder())
.dataSource(dataSource)
.usersByUsernameQuery("select name, password, enabled from t_account where name=?")
.authoritiesByUsernameQuery("select name, role from t_account_role where name=?");
}
};
}
public static void main(String[] args) {
SpringApplication.run(ToyApplication.class, args);
}
}
這樣就可以使用資料庫中相對應的名稱、密碼與角色來登入了,如果要進一步設置防護頁面:
package cc.openhome.toy;
...略
@SpringBootApplication(
scanBasePackages={
"cc.openhome.controller",
"cc.openhome.model"
}
)
public class ToyApplication {
@Bean
public WebSecurityConfigurerAdapter webSecurityConfig(DataSource dataSource) {
return new WebSecurityConfigurerAdapter() {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user/**").hasRole("MEMBER")
.and()
.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.jdbcAuthentication()
.passwordEncoder(new BCryptPasswordEncoder())
.dataSource(dataSource)
.usersByUsernameQuery("select name, password, enabled from t_account where name=?")
.authoritiesByUsernameQuery("select name, role from t_account_role where name=?");
}
};
}
public static void main(String[] args) {
SpringApplication.run(ToyApplication.class, args);
}
}
只要能找到 WebSecurityConfigurerAdapter
,Spring Boot 就會套用其中的設定;隨著應用程式逐漸複雜,也許你會想要將一些設定,移出至其他的設定檔案之中:
package cc.openhome.toy;
...略
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user/**").hasRole("MEMBER")
.and()
.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.jdbcAuthentication()
.passwordEncoder(new BCryptPasswordEncoder())
.dataSource(dataSource)
.usersByUsernameQuery("select name, password, enabled from t_account where name=?")
.authoritiesByUsernameQuery("select name, role from t_account_role where name=?");
}
}
你只要在 @SpringBootApplication
時,記得掃描設定檔所在套件就可以了:
package cc.openhome.toy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(
scanBasePackages={
"cc.openhome.controller",
"cc.openhome.model",
"cc.openhome.toy"
}
)
public class ToyApplication {
public static void main(String[] args) {
SpringApplication.run(ToyApplication.class, args);
}
}
你可以在 toy 中找到以上的範例專案。