一、项目搭建
1、创建SpringBoot项目
2、next->选择web、securitty依赖即可
3、pom.xml文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.security</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4、创建两个资源访问接口
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/mobile")
public class MobileController {
@GetMapping("/query")
public String query(){
return "mobile";
}
}
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/salary")
public class SalaryController {
@GetMapping("/query")
public String query(){
return "salary";
}
}
到这一步呢,我们就完成了一个SpringBoot工程的基础搭建。然后我们就可以启动
引用访问MobileController和SalaryController的资源了,这时就会发现,访问这两
个资源会转到一个登录页面,要求先登录。登录的用户名是user,密码会在日志中
打印(默认uuid具体细节后期讲解)。
二、用SpringBoot Security重新实现我们上个应用的认证和授权逻辑。
1、注入免密解析器PasswordEncoder和用户来源UserDetailsService
package com.security.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebConfig implements WebMvcConfigurer {
//默认Url根路径跳转到/login,此url为spring security提供
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/login");
}
//自行注入PasswordEncoder
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder(10);//BCryptPasswordEncoder(10);
}
/**
* 自行注入一个UserDetailsService
* 如果没有的话,在UserDetailsServiceAutoConfiguration中会默认注入一个包含
user用户的InMemoryUserDetailsManager
* 另外也可以采用修改configure(AuthenticationManagerBuilder auth)方法并注入
*/
@Bean
public UserDetailsService userDetailsService(){
InMemoryUserDetailsManager userDetailsManager = new
InMemoryUserDetailsManager(User.withUsername("admin").password(
passwordEncoder().encode("admin")).authorities("mobile","salary").build(),
User.withUsername("manager").password(passwordEncoder().encode("manager")).
authorities("salary").build(),
User.withUsername("worker").password(passwordEncoder().encode("worker")).
authorities("worker").build());
return userDetailsManager;
}
}
2、注入校验配置规则
package com.security.demo.config;
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.WebSecurityConfigurerAdapter;
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//链式配置拦截策略
http.csrf().disable()//关闭csrg跨域检查
.authorizeRequests()
.antMatchers("/mobile/**").hasAuthority("mobile") //配置资源 权限
.antMatchers("/salary/**").hasAuthority("salary")
.antMatchers("/common/**").permitAll() //common下的请求直接通 过
.anyRequest().authenticated() //其他请求需要登录
.and() //并行条件
.formLogin().defaultSuccessUrl("/main.html").failureUrl("/common/loginFailed"); //可从默认的login页面登录,并且登录后跳转到main.html
}
}
3、获取当前用户信息:Spring Security提供了多种获取当前用户信息的方法
package com.security.demo.controller;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
@RestController
@RequestMapping("/common")
public class LoginController {
@GetMapping("/getLoginUserByPrincipal")
public String getLoginUserByPrincipal(Principal principal){
return principal.getName();
}
@GetMapping(value = "/getLoginUserByAuthentication")
public String currentUserName(Authentication authentication) {
return authentication.getName();
}
@GetMapping(value = "/username")
public String currentUserNameSimple(HttpServletRequest request) {
Principal principal = request.getUserPrincipal();
return principal.getName();
}
@GetMapping("/getLoginUser")
public String getLoginUser(){
User user =
(User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return user.getUsername();
}
}
创建个前端页面main.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>欢迎登录</h1>
<h2>
<a href="/salary/query">查询薪资</a> </br></br>
<a href="/mobile/query">查询手机号</a>
</h2>
</body>
</html>
三、项目测试
这样就可以启动任务进行测试了。启动后,可以访问security默认提供的登录页面 http://localhost:8080/login
以admin/admin登录权限/mobile /salary访问无影响
以manager/manager登录权限/mobile受限 /salary访问无影响
以worker/worker登录权限/mobile /salary访问受限
具体测试可以自己调试