spring security简单配置
使用版本 jdk17,springboot 2.7.1
主要集中在5个类里面配置
1,实现UserDetailsService
@Configuration
public class MyUserDetailsService implements UserDetailsService {
private final Map<String, String> users = Map.of("user1", "authority1", "user2", "authority2");
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 省略在数据库查找用户,此时通用密码为123456
String password = new BCryptPasswordEncoder().encode("123456");
if (!users.containsKey(username)) {
throw new UsernameNotFoundException("没有找到用户名!!");
}
List<GrantedAuthority> grantedAuthorities = AuthorityUtils.createAuthorityList(users.get(username));
return new User(username, password, grantedAuthorities);
}
}
2,实现AuthenticationManager
@Configuration
public class MyAuthenticationManager implements AuthenticationManager {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
UserDetails userDetails = userDetailsService.loadUserByUsername(authentication.getName());
if (!passwordEncoder.matches((String) authentication.getCredentials(), userDetails.getPassword())) {
throw new BadCredentialsException("用户名或密码错误");
}
System.out.println(userDetails);
return new UsernamePasswordAuthenticationToken(authentication, authentication.getCredentials(),
userDetails.getAuthorities());
}
}
3,登录成功与失败的处理
@Configuration
public class AuthenticationHandleAdapter implements AuthenticationSuccessHandler, AuthenticationFailureHandler {
@Autowired
private ObjectMapper objectMapper;
private void write(HttpServletResponse response, Object object) {
try {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
response.getWriter().print(objectMapper.writeValueAsString(object));
response.getWriter().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
write(response, Map.of("message", "ok"));
}
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
write(response, Map.of("message", "failed: " + exception.getMessage()));
}
}
4,访问拒绝处理
@Configuration
public class MyAccessDeniedHandler implements AccessDeniedHandler {
private final ObjectMapper objectMapper;
public MyAccessDeniedHandler(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
try {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
response.getWriter().print(objectMapper.writeValueAsString(
Map.of("message", "access deny: " + accessDeniedException.getMessage())));
response.getWriter().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5,核心配置
@Configuration
public class WebSecurityConfig {
@Bean
PasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
SecurityFilterChain filterChain(HttpSecurity http,
MyAuthenticationManager authenticationManager,
MyAccessDeniedHandler accessDeniedHandler,
AuthenticationHandleAdapter authenticationHandler) throws Exception {
return http
.formLogin(customizer -> customizer
.loginPage("/loginPage")
.successHandler(authenticationHandler)
.failureHandler(authenticationHandler)
.loginProcessingUrl("/login")
)
.authorizeRequests(authorizeRequests -> authorizeRequests
.antMatchers("/hello").authenticated()
.antMatchers("/authority1").hasAuthority("authority1")
.antMatchers("/authority2").hasAuthority("authority2")
)
.exceptionHandling(exceptionHandling -> exceptionHandling
.accessDeniedHandler(accessDeniedHandler)
)
.authenticationManager(authenticationManager)
.csrf().disable()
.build();
}
}
POM文件内容添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>