大多数项目是需要安全控制的。这章用Spring Security实现用户登录功能。
创建项目
这章新创建一个模块来开发。 创建模块参考这里。模块的ArtifactId为bhuser。
项目目录结构如下图
添加组件
下面先写两个页面,需要在pom.xml文件中引入spring-boot-starter-thymeleaf。文件内容:
<?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下创建PageController。内容如下:
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中创建两个页面,分别是home.html和hello.html
home.html内容如下:
<!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内容如下:
<!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页面。
增加安全控制
现在是没有权限控制的情况下的结果。下面来增加安全控制,使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>
这时候启动项目,访问首页就会跳转到登录页面了。
这个登录页面是框架提供的。用户名和密码是框架生成的。这样的用户名密码不可控制。接下增加自己的登录认证业务。
创建包com.biboheart.demos.security,安全控制的业务写在这个包下。创建security配置文件SecurityConfiguration,内容:
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 {
// 创建内存用户
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界面。表示登录成功,允许访问界面。
简单的登录功能就实现了,后续会讲到自定义登录界面,自定义认证过程等。