我试图将路径限制为仅ADMIN。到目前为止,但这给了我<403 Forbidden>错误:
此应用程序没有 /error 的显式映射,因此您将其视为后备。 2024 年 4 月 8 日星期一 01:49:02 美国东部时间 出现意外错误(类型=禁止,状态=403)。
安全配置
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {
private final UserService userService;
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/").permitAll()
.requestMatchers("/login**", "/error**", "/resource/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.oauth2Login((userInfo) -> userInfo
.userInfoEndpoint((config) -> config.oidcUserService(userService))
)
.build();
}
用户
@Entity
@Table(name = "user")
@Data
@NoArgsConstructor
public class UserEntity implements Serializable, UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(unique = true)
private String username;
@Column
private String password;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
@JoinTable(name = "user_roles",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
private Set<Role> roles = new HashSet<>();
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles();
}
角色
@Entity
@Table(name = "role")
@AllArgsConstructor
@NoArgsConstructor
@Getter @Setter
public class Role implements GrantedAuthority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(unique = true)
private String name;
@Override
public String getAuthority() {
return name;
}
}
用户服务
@Service
@AllArgsConstructor
public class UserService extends OidcUserService {
private final UserRepository userRepository;
private final RoleRepository roleRepository;
@Override
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
OidcUser oidcUser = super.loadUser(userRequest);
try {
return processOidcUser(userRequest, oidcUser);
} catch (Exception e) {
throw new InternalAuthenticationServiceException(e.getMessage(), e.getCause());
}
}
private OidcUser processOidcUser(OidcUserRequest userRequest, OidcUser oidcUser) {
GoogleUserInfo googleUserInfo = new GoogleUserInfo(oidcUser.getAttributes());
Optional<UserEntity> userOptional = userRepository.findByUsername(googleUserInfo.getEmail());
if (userOptional.isEmpty()) {
UserEntity user = new UserEntity();
user.setUsername(googleUserInfo.getEmail());
user.setPassword(googleUserInfo.getName());
Role role = roleRepository.findByName("ADMIN");
user.getRoles().add(role);
userRepository.save(user);
}
return oidcUser;
}
}
我尝试使用 accessDeniedHandler 进行调试,但找不到出路。
这也没有帮助:
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
.requestMatchers("/admin/**").hasAuthority("ADMIN")
感谢您的帮助!有任何意见欢迎欢迎
我在 processOidcUser 中返回相同的 oidcUser。所以我为它创建了 CustomOidcUser。
public class CustomOidcUser implements OidcUser {
private final OidcUser oidcUser;
private final Set<Role> roles;
@Override
public Map<String, Object> getClaims() {
return oidcUser.getClaims();
}
@Override
public OidcUserInfo getUserInfo() {
return oidcUser.getUserInfo();
}
@Override
public OidcIdToken getIdToken() {
return oidcUser.getIdToken();
}
@Override
public Map<String, Object> getAttributes() {
return oidcUser.getAttributes();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles();
}
@Override
public String getName() {
return oidcUser.getFullName();
}
}
然后更改 UserService 为 loadUser 返回自定义 oidcUser。
public class UserService extends OidcUserService {
private final UserRepository userRepository;
private final RoleRepository roleRepository;
@Override
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
OidcUser oidcUser = super.loadUser(userRequest);
try {
return processOidcUser(oidcUser);
} catch (Exception e) {
throw new InternalAuthenticationServiceException(e.getMessage(), e.getCause());
}
}
private OidcUser processOidcUser(OidcUser oidcUser) {
GoogleUserInfo googleUserInfo = new GoogleUserInfo(oidcUser.getAttributes());
Optional<UserEntity> userOptional = userRepository.findByUsername(googleUserInfo.getEmail());
if (userOptional.isEmpty()) {
UserEntity user = new UserEntity();
user.setUsername(googleUserInfo.getEmail());
user.setPassword(googleUserInfo.getName());
Role role = roleRepository.findByName("USER");
user.getRoles().add(role);
userOptional = Optional.of(userRepository.save(user));
}
return new CustomOidcUser(oidcUser, userOptional.get().getRoles());
}
}