這是
官網上的文章節錄,說明怎麼開始用 spring security 控制 web 的權限,一個很簡單的 hello 程式,第一頁是首頁,如下:
按了 here 後,會出現登入頁,如下:
輸入帳號密碼,為求簡單,程式裡先 hard code 為 user / password,輸入後按【Sign In】登入就出現 Hello 畫面,如下:
現在開始寫程式 ...
如上,在 eclipse 中以「Spring Starter Project」建立一個 spring boot 檔案,會得到如上的檔案結構,當然,裡面的程式是下面要開始慢慢加進去的。
buildscript {
ext {
springBootVersion = '2.0.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'idv.steven.mysecurity'
version = '0.0.1'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-web')
compileOnly('org.projectlombok:lombok')
testCompile("junit:junit")
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.security:spring-security-test')
}
在 build.gradle 寫入如上內容,因為這個程式除了會用到 spring security 外,會以 web 的方式寫程式,所以也引入 web 相關 jar 檔。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example</title>
</head>
<body>
<h1>Welcome!</h1>
<p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example </title>
</head>
<body>
<div th:if="${param.error}">
Invalid username and password.
</div>
<div th:if="${param.logout}">
You have been logged out.
</div>
<form th:action="@{/login}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Hello World!</title>
</head>
<body>
<h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
<form th:action="@{/logout}" method="post">
<input type="submit" value="Sign Out"/>
</form>
</body>
</html>
package idv.steven.mysecurity;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
}
WebMvcConifgurer 是 spring MVC 的一個類別,繼承它之後覆寫 addViewControllers method,可以注冊一些網址與網頁的對應。
package idv.steven.mysecurity;
import org.springframework.context.annotation.Bean;
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;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
@Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
要啟用 spring security,要在一個有 @Configuration 的類別前加上 @EnableWebSecurity,要改變預設的安全設定,則繼承 WebSecurityConfigurerAdapter,再覆寫相關的 method。這裡覆寫了 configure method 變更相關權限,從程式就很容易看得出來是什麼意思 (英文就寫的很清楚了),formLogin() 表示要使用 Form-Based login 的方式登入,登入頁為 /login,所有人都可以開啟這一個網頁。
spring security 在驗證帳密時,會由 spring container 中取得 UserDetailService 的 object 來驗證,上面的程式產生一個 UserDetailsService 的 Bean,把帳密放在記憶體裡,只有一個使用者,名稱為 user,密碼為 password,角色是 USER。一般的系統不會把帳密放記憶體,通常是放在 LDAP 或資料庫,下一篇會說明當放在資料庫時怎麼做。
- MySecurityApplication.java
package idv.steven.mysecurity;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MySecurityApplication {
public static void main(String[] args) {
SpringApplication.run(MySecurityApplication.class, args);
}
}
這個類別應該沒有懸念,spring boot 都是由標有 @SpringBootApplication 的 main 所在類別開始的。