大多數(shù)項目是需要安全控制的。這章用Spring Security實現(xiàn)用戶登錄功能。
創(chuàng)建項目
這章新創(chuàng)建一個模塊來開發(fā)。 創(chuàng)建模塊參考這里。模塊的ArtifactId為bhuser。

項目目錄結構如下圖

添加組件
下面先寫兩個頁面,需要在pom.xml文件中引入spring-boot-starter-thymeleaf。文件內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>bhparent</artifactId>
<groupId>com.biboheart.demos</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bhuser</artifactId>
<name>bhuser</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
</project>
控制器
既然是安全控制,就需要有控制的點。這里寫兩個Controller,分別是兩個界面。到最后的目標是一個界面不需要登錄就可以瀏覽,一個界面需要用戶登錄后才能瀏覽。
在包com.biboheart.demos.controller下創(chuàng)建PageController。內(nèi)容如下:
package com.biboheart.demos.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class PageController {
@RequestMapping(value = { "/", "/home" }, method = RequestMethod.GET)
public String homePage() {
return "home";
}
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
return "hello";
}
}
在sources/templates中創(chuàng)建兩個頁面,分別是home.html和hello.html
home.html內(nèi)容如下:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Security Example</title>
</head>
<body>
<h1>Welcome!</h1>
<p>
點擊 <a th:href="@{/hello}">這里</a> 查看信息.
</p>
</body>
</html>
hello.html內(nèi)容如下:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello World!</title>
</head>
<body>
<h1 th:inline="text">Hello</h1>
</body>
</html>
啟動服務后,訪問localhost

點擊連接“這里”進入hello頁面。

增加安全控制
現(xiàn)在是沒有權限控制的情況下的結果。下面來增加安全控制,使home頁面可以訪問,hello頁面需要用戶登錄才能訪問。
在pom.xml中引入spring-boot-starter-security組件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>bhparent</artifactId>
<groupId>com.biboheart.demos</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bhuser</artifactId>
<name>bhuser</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
</project>
這時候啟動項目,訪問首頁就會跳轉到登錄頁面了。

這個登錄頁面是框架提供的。用戶名和密碼是框架生成的。這樣的用戶名密碼不可控制。接下增加自己的登錄認證業(yè)務。
創(chuàng)建包com.biboheart.demos.security,安全控制的業(yè)務寫在這個包下。創(chuàng)建security配置文件SecurityConfiguration,內(nèi)容:
package com.biboheart.demos.security;
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.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 創(chuàng)建內(nèi)存用戶
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder.encode("123")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder.encode("admin")).roles("USER", "ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll() // 這三個目錄不做安全控制
.anyRequest().authenticated()
.and()
.formLogin().permitAll(); // 登錄不需要安全控制
}
// spring security 必須有一個passwordEncoder
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
注意,Spring Security 5必須配置 passwordEncoder。
重啟服務,訪問localhost

點擊連接“這里”,跳轉到了login界面

輸入用戶名: user,密碼: 123。點擊Sign in。進入hello界面。表示登錄成功,允許訪問界面。

簡單的登錄功能就實現(xiàn)了,后續(xù)會講到自定義登錄界面,自定義認證過程等。