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

項(xiàng)目目錄結(jié)構(gòu)如下圖

添加組件
下面先寫(xiě)兩個(gè)頁(yè)面,需要在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>
控制器
既然是安全控制,就需要有控制的點(diǎn)。這里寫(xiě)兩個(gè)Controller,分別是兩個(gè)界面。到最后的目標(biāo)是一個(gè)界面不需要登錄就可以瀏覽,一個(gè)界面需要用戶登錄后才能瀏覽。
在包c(diǎn)om.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)建兩個(gè)頁(yè)面,分別是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>
點(diǎn)擊 <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>
啟動(dòng)服務(wù)后,訪問(wèn)localhost

點(diǎn)擊連接“這里”進(jìn)入hello頁(yè)面。

增加安全控制
現(xiàn)在是沒(méi)有權(quán)限控制的情況下的結(jié)果。下面來(lái)增加安全控制,使home頁(yè)面可以訪問(wèn),hello頁(yè)面需要用戶登錄才能訪問(wèn)。
在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>
這時(shí)候啟動(dòng)項(xiàng)目,訪問(wèn)首頁(yè)就會(huì)跳轉(zhuǎn)到登錄頁(yè)面了。

這個(gè)登錄頁(yè)面是框架提供的。用戶名和密碼是框架生成的。這樣的用戶名密碼不可控制。接下增加自己的登錄認(rèn)證業(yè)務(wù)。
創(chuàng)建包c(diǎn)om.biboheart.demos.security,安全控制的業(yè)務(wù)寫(xiě)在這個(gè)包下。創(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() // 這三個(gè)目錄不做安全控制
.anyRequest().authenticated()
.and()
.formLogin().permitAll(); // 登錄不需要安全控制
}
// spring security 必須有一個(gè)passwordEncoder
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
注意,Spring Security 5必須配置 passwordEncoder。
重啟服務(wù),訪問(wèn)localhost

點(diǎn)擊連接“這里”,跳轉(zhuǎn)到了login界面

輸入用戶名: user,密碼: 123。點(diǎn)擊Sign in。進(jìn)入hello界面。表示登錄成功,允許訪問(wèn)界面。

簡(jiǎn)單的登錄功能就實(shí)現(xiàn)了,后續(xù)會(huì)講到自定義登錄界面,自定義認(rèn)證過(guò)程等。