#00后送爸爸的第一台新能源#
package com.alatus.secrurity.config;
import com.alatus.secrurity.entity.User;
import com.alatus.secrurity.mapper.UserMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
@Component
public class DBUserDetailsManager implements UserDetailsManager, UserDetailsPasswordService {
@Resource
private UserMapper userMapper;
@Override
public UserDetails updatePassword(UserDetails user, String newPassword) {
return null;
}
@Override
public void createUser(UserDetails userDetails) {
User userSave = new User();
userSave.setUsername(userDetails.getUsername());
userSave.setPassword(userDetails.getPassword());
userSave.setEnable(true);
userMapper.insert(userSave);
}
@Override
public void updateUser(UserDetails user) {
}
@Override
public void deleteUser(String username) {
}
@Override
public void changePassword(String oldPassword, String newPassword) {
}
@Override
public boolean userExists(String username) {
return false;
}
// 从数据库中获取用户信息
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
if(user == null){
throw new UsernameNotFoundException("用户不存在");
}
else{
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return "USER_ADD";
}
});
// return new org.springframework.security.core.userdetails.User(
// user.getUsername(),
// user.getPassword(),
// user.getEnable(),
// true,
// true,
// true,
// authorities
// );
return org.springframework.security.core.userdetails.User.withUsername(user.getUsername())
.password(user.getPassword())
.disabled(!user.getEnable())
.credentialsExpired(false)
.accountLocked(false)
// 这两兄弟不能同时存在,会彼此覆盖掉,要么直接限定角色,角色再绑定权限,要么直接给对应用户以权限(这种不太合理)
.roles("ADMIN")
.authorities("USER_ADD","USER_DELETE")
.build();
}
}
}
package com.alatus.secrurity.config;
import com.alatus.secrurity.handler.*;
import com.alatus.secrurity.strategy.MySessionInformationExpiredStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration
//开启Spring Security的自定义配置
@EnableWebSecurity
@EnableMethodSecurity//开启Spring Security的权限控制,基于方法授权
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) -> {
authorize
// .requestMatchers("/login").permitAll()
// .requestMatchers("/logout").permitAll()
// .requestMatchers("/user/**").hasRole("ADMIN")
// .requestMatchers("/user/list").hasAuthority("USER_LIST")
// .requestMatchers("/user/add").hasAuthority("USER_ADD")
.anyRequest()//对所有请求开启授权保护
.authenticated();//已认证的请求会被自动授权
});
http.formLogin(formLogin->{
formLogin.loginPage("/login").permitAll()
// 修改自定义的表单参数
.usernameParameter("myUsername")
.passwordParameter("myPassword")
.failureUrl("/login?failure")
.failureHandler(new MyAuthenticationFailureHandler())
// 这里将默认的登录成功handler改为我们自定义的handler
.successHandler(new MyAuthenticationSuccessHandler());
//如果不配置permitAll,就会导致出现login页是初始登录页,但是这个页面资源又收到保护,导致跳转回登录页
//但是登录页又收到保护,于是又要跳转到登录页,就会形成页面递归导致报错
});
http.logout((Logout)->{
Logout.logoutSuccessHandler(new MyLogoutSuccessHandler());
});
http.exceptionHandling(exceptionHandling->{
exceptionHandling.authenticationEntryPoint(new MyAuthenticationEntryPoint());//请求未认证的处理
exceptionHandling.accessDeniedHandler(new MyAccessDeniedHandler());
});
http.csrf(csrf->csrf.disable());
http.cors(withDefaults());
http.sessionManagement(sessionManagement->{
sessionManagement.maximumSessions(1)//最大几个客户端给用户登录
.maxSessionsPreventsLogin(true)
.expiredSessionStrategy(new MySessionInformationExpiredStrategy());
});
http.cors(withDefaults());
return http.build();
}
// @Bean
// public UserDetailsService userDetailsService() {
//// 创建基于内存的用户信息管理器
//// InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
//// 创建基于数据库的用户信息管理器
// DBUserDetailsManager manager = new DBUserDetailsManager();
//// 创建UserDetails对象,并设置用户名、密码、角色权限等内容
//// 因为用户都在数据库创建保存和查询,所以这里我们使用数据库中的用户信息进行登录验证
//// manager.createUser(User.withDefaultPasswordEncoder().username("admin").password("admin").roles("USER").build());
//// 这里我们的manager对象用于管理我们创建的用户信息
// return manager;
// }
}
package com.alatus.secrurity.app;
import com.alatus.secrurity.entity.User;
import com.alatus.secrurity.service.UserService;
import com.alibaba.fastjson.JSON;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@GetMapping("/list")
@PreAuthorize("hasRole('ADMIN') and authentication.name == 'admin'")
public String userShow(){
List<User> list = userService.list();
System.out.println(list.size());
for (User user : list) {
System.out.println("User ID: " + user.getId());
System.out.println("Username: " + user.getUsername());
System.out.println("Password: " + user.getPassword());
System.out.println("Enabled: " + user.getEnable());
}
for (User user : list) {
System.out.println(JSON.toJSONString(user));
}
return JSON.toJSONString(list);
}
@PostMapping("/register")
// @PreAuthorize("hasRole('USER')")
@PreAuthorize("hasAuthority('USER_ADD')")
public String register(@RequestBody User user){
userService.saveUserDetails(user);
return "注册成功";
}
}
package com.alatus.secrurity.handler;
import com.alibaba.fastjson.JSON;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
Map<String, Object> result = new HashMap<>();
result.put("code", 0);
result.put("msg", "注销成功");
result.put("data", authentication.getPrincipal());
String json = JSON.toJSONString(result);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
}
}