✨ 自定义UserDetailsService
This commit is contained in:
parent
285d9272f4
commit
6579c15627
|
@ -255,4 +255,42 @@ public class MD5PasswordEncoder implements PasswordEncoder {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 自定义UserDetailsService
|
||||
|
||||
在Spring Security中,如果需要自定义用户认证逻辑,可以通过实现`UserDetailsService`接口来完成。以下是正确实现方式:
|
||||
|
||||
### 标准实现示例
|
||||
|
||||
```java
|
||||
@Service
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
// 推荐使用构造器注入
|
||||
public CustomUserDetailsService(PasswordEncoder passwordEncoder) {
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
// 1. 这里应该根据username从数据库或其他存储中查询用户信息
|
||||
// 以下是模拟数据,实际应用中应从数据库查询
|
||||
|
||||
// 2. 如果用户不存在,抛出UsernameNotFoundException
|
||||
if (!"bunny".equalsIgnoreCase(username)) {
|
||||
throw new UsernameNotFoundException("User not found: " + username);
|
||||
}
|
||||
|
||||
// 3. 构建UserDetails对象返回
|
||||
return User.builder()
|
||||
.username(username) // 使用传入的用户名
|
||||
.password(passwordEncoder.encode("123456")) // 密码应该已经加密存储,这里仅为示例
|
||||
.roles("USER") // 角色会自动添加ROLE_前缀
|
||||
.authorities("read", "write") // 添加具体权限
|
||||
.build();
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,11 +1,14 @@
|
|||
package com.spring.security.config;
|
||||
|
||||
import com.spring.security.handler.SecurityAccessDeniedHandler;
|
||||
import com.spring.security.handler.SecurityAuthenticationEntryPoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
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.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@EnableMethodSecurity
|
||||
|
@ -18,7 +21,7 @@ public class SecurityWebConfiguration {
|
|||
String[] permitAllUrls = {
|
||||
"/", "/doc.html/**",
|
||||
"/webjars/**", "/images/**", ".well-known/**", "favicon.ico", "/error/**",
|
||||
"/v3/api-docs/**"
|
||||
"/swagger-ui/**", "/v3/api-docs/**"
|
||||
};
|
||||
|
||||
http.authorizeHttpRequests(authorizeRequests ->
|
||||
|
@ -49,7 +52,14 @@ public class SecurityWebConfiguration {
|
|||
.logout(logout -> logout
|
||||
.logoutSuccessUrl("/login-page?logout=true")
|
||||
.permitAll()
|
||||
);
|
||||
)
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.exceptionHandling(configurer -> configurer
|
||||
.accessDeniedHandler(new SecurityAccessDeniedHandler())
|
||||
.authenticationEntryPoint(new SecurityAuthenticationEntryPoint())
|
||||
)
|
||||
;
|
||||
|
||||
return http.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.spring.security.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
// 1. 这里应该根据username从数据库或其他存储中查询用户信息
|
||||
// 以下是模拟数据,实际应用中应从数据库查询
|
||||
|
||||
// 2. 如果用户不存在,抛出UsernameNotFoundException
|
||||
if (!"bunny".equalsIgnoreCase(username)) {
|
||||
throw new UsernameNotFoundException("User not found: " + username);
|
||||
}
|
||||
|
||||
// 3. 构建UserDetails对象返回
|
||||
return User.builder()
|
||||
.username(username) // 使用传入的用户名
|
||||
.password(passwordEncoder.encode("123456")) // 密码应该已经加密存储,这里仅为示例
|
||||
.roles("USER") // 角色会自动添加ROLE_前缀
|
||||
.authorities("read", "write") // 添加具体权限
|
||||
.build();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue