1、安装依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2、代码结构
3、分别新建测试实体类User和Role
@Data
public class User {
private Long id;
private String userName;
private String sex;
private String userCode;
private String passWord;
}
@Data
public class Role {
private Long id;
private String roleName;
}
4、实现用户详情构造器UserDetailsServiceConfig类(具体通常是有数据库查询出来的)
package com.example.springsecuretest.secureConfig;
import com.example.springsecuretest.entity.Role;
import com.example.springsecuretest.entity.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class UserDetailsServiceConfig implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("用户信息");
System.out.println(username);
//根据实际业务查询的用户信息
User user=new User();
user.setId(1L);
user.setUserCode("001");
user.setUserName("admin");
user.setPassWord("1234abcd");
//角色部分,根据实际业务进行查询
Role role1=new Role();
role1.setId(1L);
role1.setRoleName("ROLE_USER");
Role role2=new Role();
role2.setId(2L);
role2.setRoleName("ROLE_ADMIN");
List<Role> roles=new ArrayList<>();
roles.add(role1);
roles.add(role2);
return this.changeToUser(user,roles);
}
private UserDetails changeToUser(User user,List<Role> roleList){
PasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
String passWordStr=passwordEncoder.encode(user.getPassWord());
//权限列表
List<GrantedAuthority> authorityList=new ArrayList<>();
//赋予查询到的角色
for(Role role : roleList){
GrantedAuthority authority = new SimpleGrantedAuthority(role.getRoleName());
authorityList.add(authority);
}
UserDetails userDetails=new org.springframework.security.core.userdetails.User(user.getUserName(), passWordStr, authorityList);
return userDetails;
}
}
5、建立配置类springSecureConfig
package com.example.springsecuretest.secureConfig;
import org.springframework.beans.factory.annotation.Autowired;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.sql.DataSource;
@Configuration
public class springSecureConfig extends WebSecurityConfigurerAdapter{
@Autowired
private UserDetailsServiceConfig userDetailsServiceConfig;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
PasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
//一、使用内存签名服务
//方式1
// auth.inMemoryAuthentication()
// .passwordEncoder(passwordEncoder)
// .withUser("admin")
// .password(passwordEncoder.encode("abc"))
// .roles("USER","ADMIN")
// .and()
// .withUser("myuser")
// .password(passwordEncoder.encode("123456"))
// .roles("USER");
//方式2(内存存储方式,推荐测试)
// InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> userConfig=auth.inMemoryAuthentication().passwordEncoder(passwordEncoder);
// userConfig.withUser("admin")
// .password(passwordEncoder.encode("abc"))
// .roles("USER","ADMIN");
// userConfig.withUser("myuser")
// .password(passwordEncoder.encode("123456"))
// .roles("USER");
//二、使用数据库签名
// auth.jdbcAuthentication()
// .passwordEncoder(passwordEncoder)
// .dataSource()
// .usersByUsernameQuery()
// .authoritiesByUsernameQuery()
//新方式,推荐
auth.userDetailsService(userDetailsServiceConfig)
.passwordEncoder(passwordEncoder);
}
/**
* 限制请求
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
// .
// ("/test/mytest").hasAnyRole("ADMIN","USER") //为路径赋予角色,限定请求
// .regexMatchers("/test/mytestuser").hasAnyRole("ADMIN") //正则式的匹配
.antMatchers("/test/mytest").hasAnyRole("ADMIN","USER") //为路径赋予角色,限定请求
.antMatchers("/test/mytestuser").hasAnyRole("ADMIN")
.anyRequest().permitAll()
.and().anonymous()//允许匿名访问
.and().rememberMe() //记住我
.and().formLogin().and().httpBasic();
//spring 表达式
// http.authorizeRequests()
// .antMatchers("/test/mytest").access("hasAnyRole('ADMIN') or hasAnyRole('USER')") //为路径赋予角色,限定请求
// .antMatchers("/test/mytestuser").access("hasAnyRole('ADMIN')")
// .anyRequest().permitAll()
// .and().rememberMe() //使用记住我功能
// .and().anonymous()//允许匿名访问
// .and().formLogin().and().httpBasic();
//强制使用https
// http.requiresChannel().antMatchers("/test/mytest").requiresSecure()//使用https
// .and().requiresChannel().antMatchers("/test/mytestuser").requiresInsecure()//不适用https
// .and().authorizeRequests()
// .antMatchers("/test/mytest").hasAnyRole("ADMIN","USER") //为路径赋予角色,限定请求
// .antMatchers("/test/mytestuser").hasAnyRole("ADMIN")
// .anyRequest().permitAll()
// .and().anonymous()//允许匿名访问
// .and().formLogin().and().httpBasic();
}
}
6、测试控制器
package com.example.springsecuretest.controller;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/test")
@RestController
public class secureTest {
@GetMapping("/mytest")
public String mytest(){
return "OK";
}
@GetMapping("/mytestuser")
public String mytestuser(){
return "OK1";
}
@GetMapping("/mytest2")
public String mytest2(){
return "OK2";
}
}