项目依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.7.3</version>
</dependency>
基于内存的多用户支持
- 在项目中创建三个controller

package com.lzd.springsecuritydemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/admin/api/")
public class AdminController {
@GetMapping("hello/")
public String hello(){
return "hello, admin!";
}
}
package com.lzd.springsecuritydemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/app/api/")
public class AppController {
@GetMapping("hello/")
public String hello() {
return "hello, app!";
}
}
package com.lzd.springsecuritydemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user/api/")
public class UserController {
@GetMapping("hello/")
public String hello() {
return "hello, user!";
}
}
- 在config包下创建资源授权配置
/app/api/下的内容是面向客户的,不需要登录也能访问 /user/api/下的内容是用户操作自身数据相关api,需要登录 /admin/api/必须管理员权限才能进行操作
package com.lzd.springsecuritydemo.config;
import jdk.nashorn.internal.runtime.logging.Logger;
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;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.antMatchers("/admin/api/**").hasRole("ADMIN")
.antMatchers("/user/api/**").hasRole("USER")
.antMatchers("/app/api/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and()
.csrf().disable();
}
}
 访问http://localhost:8080/app/api/hello/ 权限是公开的  访问访问http://localhost:8080/user/api/hello/ 需要进行登录,获取USER角色权限 
 访问访问http://localhost:8080/admin/api/hello/,也是需要登录
- 基于内存来创建用户
创建类UserDetailsServiceImpl 
package com.lzd.springsecuritydemo.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.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.stereotype.Service;
@Configuration
public class UserDetailsServiceImpl {
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password("123").roles("USER").build());
manager.createUser(User.withUsername("admin").password("123").roles("USER","ADMIN").build());
return manager;
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
 InMemoryUserDetailsManager是UserDetailsService接口中的一个实现类,它将用户数据源寄存在内存里面,在不需要引入数据库的这种重数据源的系统中可以使用。 仅调用createUser()生成两个用户,并赋予角色。多次重启服务页不会出现问题
基于默认数据库认证授权
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
在resources下application.properties里配置数据源
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.url=jdbc:mysql://xxx.xxx.xxx:3306/springdemo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
创建数据库
create table users(username varchar(50) not null primary key,password varchar(500) not null,enabled boolean not null);
create table authorities (username varchar(50) not null,authority varchar(50) not null,constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);
-
users表用来存放用户名、密码和是否可用三个信息 -
authorities 表用来存放用户名及其权限对应关系 UserDetailsServiceImpl.java
package com.lzd.springsecuritydemo.config;
import org.springframework.beans.factory.annotation.Autowired;
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.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
@Configuration
public class UserDetailsServiceImpl {
@Autowired
private DataSource dataSource;
@Bean
public UserDetailsService userDetailsService() {
JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
manager.setDataSource(dataSource);
if(!manager.userExists("user")){
manager.createUser(User.withUsername("user").password("123").roles("USER").build());
}
if (!manager.userExists("admin")) {
manager.createUser(User.withUsername("admin").password("123").roles("USER","ADMIN").build());
}
return manager;
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
启动项目:数据库会自动生成数据   ==ROLE_==前缀是默认加上的
- 与前面基于内存创建用户的区别,如果这里不加判断,每次启动项目都会执行一次创建用户的sql命令,则会报错。
if(!manager.userExists("user")){
manager.createUser(User.withUsername("user").password("123").roles("USER").build());
}
接着可用测试访问api了。
|