基于内存中的用户信息:
继承类,重写方法,来实现自定义认证信息
@Configuration //相当于配置类,返回值是Java对象,对象放到spring容器之中 @EnableWebSecurity//表示启用安全框架功能
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
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.method.configuration.EnableGlobalMethodSecurity;
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;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
//启用方法级别的认证 ,表示可以启用@preAuthorize 和@postAuthorize
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
//方法中配置用户和密码的信息,作为登录的信息
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder pe = passwordEncoder();
auth.inMemoryAuthentication()
.withUser("zhangsan")
.password(pe.encode("123456"))
.roles("normal");
auth.inMemoryAuthentication()
.withUser("lisi")
.password(pe.encode("123456"))
.roles("normal");
auth.inMemoryAuthentication()
.withUser("admin")
.password(pe.encode("admin"))
.roles("admin","normal");
}
@Bean
public PasswordEncoder passwordEncoder(){
//实现类,实现类是加密算法
return new BCryptPasswordEncoder();
}
}
//controller
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String sauHello(){
return "使用内存中的用户信息";
}
//指定normal和admin角色可以访问的方法
@RequestMapping("/helloUser")
@PreAuthorize(value = "hasAnyRole('admin','normal')")
public String HelloUser(){
return "HEllo 拥有normal以及admin角色的用户";
}
@RequestMapping("/helloAdmin")
@PreAuthorize(value = "hasAnyRole('admin')")
public String HelloAdmin(){
return "HEllo 拥有admin角色的用户";
}
}
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
5版本要求必须加密!
基于角色的Role的身份认证,同一个用户可以有不同的角色。同时可以开启对方法级别的
1.设置用户的角色
继承WebSecurityConfigurerAdapter
重写configure方法,指定用户的roles
2.在类的上面加入启用方法级别的注解
//启用方法级别的认证 ,表示可以启用@preAuthorize 和@postAuthorize @EnableGlobalMethodSecurity(prePostEnabled = true)
3.在处理器方法的上面加入角色的信息,指定方法可以访问的角色列表。
@PreAuthorize(value = "hasAnyRole('admin','normal')")
基于JDBC用户认证
从Mysql获取用户的身份信息(用户名称,密码,角色)
1.在spring security框架对象用户信息的表示类是UserDetails
UserDetails 是一个接口,高度抽象的用户信息类
User类:是UserDetails接口的实现类,构造方法有三个参数:username,password,authorities,需要向spring security提供user对象
2.实现userDetailsService接口。
重写方法userDetails loadUserByname()
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
//启用方法级别的认证 ,表示可以启用@preAuthorize 和@postAuthorize
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("MyUserDetailService")
private UserDetailsService userDetailsService;
//方法中配置用户和密码的信息,作为登录的信息
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String sauHello(){
return "使用内存中的用户信息";
}
//指定normal和admin角色可以访问的方法
@RequestMapping("/helloUser")
@PreAuthorize(value = "hasAnyRole('admin','normal')")
public String HelloUser(){
return "HEllo 拥有normal以及admin角色的用户";
}
@RequestMapping("/helloAdmin")
@PreAuthorize(value = "hasAnyRole('admin')")
public String HelloAdmin(){
return "HEllo 拥有admin角色的用户";
}
}
import cn.tedu.entity.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserInfoDao extends JpaRepository<UserInfo,Long> {
//按照username查询数据库信息
UserInfo findByUsername(String username);
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
//当前类是一个实体类,表示数据库中的一个表
@Entity
public class UserInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String role;
}
import cn.tedu.dao.UserInfoDao;
import cn.tedu.entity.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class JdbcInit {
@Autowired
private UserInfoDao dao;
@PostConstruct
public void init(){
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
UserInfo u=new UserInfo();
u.setUsername("zhangsan");
u.setPassword(encoder.encode("123456"));
u.setRole("normal");
dao.save(u);
u=new UserInfo();
u.setUsername("admin");
u.setPassword(encoder.encode("admin"));
u.setRole("admin");
dao.save(u);
}
}
import cn.tedu.dao.UserInfoDao;
import cn.tedu.entity.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component("MyUserDetailService")
public class MyUserDetailService implements UserDetailsService {
@Autowired
private UserInfoDao dao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo=null;
User user=null;
if(username !=null){
userInfo=dao.findByUsername(username);
}
if(userInfo!=null) {
List<GrantedAuthority> list = new ArrayList<>();
//角色固定写法
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"+userInfo.getRole());
list.add(authority);
user = new User(userInfo.getUsername(),userInfo.getPassword(),list);
}
//创建User对象
return user;
}
}
//application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/springdb
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.generate-ddl=false
spring.jpa.show-sql=true
spring.jpa.database=mysql
#自动生成
spring.jpa.hibernate.ddl-auto=update