一、依赖看上一节的
二、建表语句
CREATE TABLE `letter_user_info` (
`uid` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL COMMENT '用户名称',
`password` varchar(64) NOT NULL COMMENT '密码',
`role` varchar(64) NOT NULL COMMENT '角色',
`del` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`uid`),
KEY `del` (`del`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
三、代码
1、配置文件
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} -%msg%n
spring.datasource.url=jdbc:mysql://localhost:3306/letter?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
2、Service、 DAO 、Controller、Config 、Entity
1)entity
package com.hao.flame.entity;
import lombok.Data;
import lombok.ToString;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
/**
* @author haoxiansheng
* @date 2020-05-31
* 存储用户的名称、密码
*/
@Entity
@Table(name = "letter_user_info")
@Data
@ToString
public class UserInfo {
@Id
@GenericGenerator(name = "idGenerator", strategy = "uid")
@GeneratedValue(strategy = GenerationType.IDENTITY)//声明主键自增
private long uid; //主键
private String name; // 用户名
private String password; // 密码
@Enumerated(EnumType.STRING)
private Role role;
private boolean del;
public enum Role {
admin, normal
}
}
2)DAO
package com.hao.flame.dao;
import com.hao.flame.entity.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
/**
* @author haoxiansheng
* @date 2020-05-31
*/
@Repository
public interface UserInfoRepository extends JpaRepository<UserInfo, Integer> {
Optional<UserInfo> findByName(String name);
}
3)Service
package com.hao.flame.service;
import com.hao.flame.entity.UserInfo;
import java.util.Optional;
/**
* @author haoxiansheng
* @date 2020-05-31
*/
public interface UserInfoService {
Optional<UserInfo> findUserInfoByUserName(String name);
}
package com.hao.flame.service;
import com.hao.flame.dao.UserInfoRepository;
import com.hao.flame.entity.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;
/**
* @author haoxiansheng
* @date 2020-05-31
*/
@Service
public class UserInfoServiceImpl implements UserInfoService {
@Autowired
private UserInfoRepository userInfoRepository;
@Override
public Optional<UserInfo> findUserInfoByUserName(String name) {
return userInfoRepository.findByName(name);
}
}
4) Config
package com.hao.flame.security;
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;
/**
* @author haoxiansheng
* @date 2020-05-31
*/
@Configuration
@EnableWebSecurity //启用Spring Security
@EnableGlobalMethodSecurity(prePostEnabled = true) //会拦截了@PreAuthrize注解的配置
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean // 注入PasswordEncoder
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
package com.hao.flame;
import com.hao.flame.entity.UserInfo;
import com.hao.flame.service.UserInfoService;
import lombok.extern.slf4j.Slf4j;
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.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* @author haoxiansheng
* @date 2020-05-31
*/
@Component
@Slf4j
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserInfoService userInfoService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String usesName) throws UsernameNotFoundException {
log.info("loadUserByUsername==========>usesName={}", usesName);
/**
* 1、通过username 获取到userInfo信息
* 2、通过User(UserDetails) 返回UserDetails
*/
Optional<UserInfo> userInfo = userInfoService.findUserInfoByUserName(usesName);
if (!userInfo.isPresent()) {
throw new UsernameNotFoundException("userName is not fond");
}
return userInfo.map(this::assmbleUser).get();
}
private UserDetails assmbleUser(UserInfo userInfo) {
List<GrantedAuthority> authorities = new ArrayList<>(10);
authorities.add(new SimpleGrantedAuthority("ROLE_" + userInfo.getRole().name()));
return new User(userInfo.getName(), passwordEncoder.encode(userInfo.getPassword()), authorities);
}
}
5) Controller
package com.hao.flame.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author haoxiansheng
* @date 2020-05-30
*/
@RestController
@RequestMapping("/demo")
public class DemoController {
@GetMapping()
public Object getDemo() {
return "String";
}
@GetMapping("/helloAdmin")
@PreAuthorize("hasAnyRole('admin')")
public String helloAdmin() {
return "hello, admin";
}
@PreAuthorize("hasAnyRole('admin', 'normal')")
@GetMapping("/helloUser")
public String helloUser() {
return "hello, user";
}
}
6) 初始化数据 这我用了@PostConstruct 也可以直接在数据插入两条数据
package com.hao.flame.init;
import com.hao.flame.dao.UserInfoRepository;
import com.hao.flame.entity.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
/**
* @author haoxiansheng
* @date 2020-05-31
*/
@Service
public class DataInit {
@Autowired
private UserInfoRepository userInfoRepository;
@PostConstruct // 让这个方法在初始化的时候可以执行
public void dataInit() {
UserInfo admin = new UserInfo();
admin.setName("admin");
admin.setPassword("123");
admin.setRole(UserInfo.Role.admin);
userInfoRepository.save(admin);
UserInfo user = new UserInfo();
user.setName("user");
user.setPassword("123");
user.setRole(UserInfo.Role.normal);
userInfoRepository.save(user);
}
}