【发布时间】:2019-07-17 04:24:24
【问题描述】:
当用户尝试使用已暂停、锁定或无效的帐户调用我的网络服务时,我试图显示自定义错误。
问题是,无论我尝试什么,都会不断返回相同的消息:“访问此资源需要完全身份验证”
我的 CustomUserDetailsService 是这样的:
@Service
public class CustomUserDetailsService implements UserDetailsService {
private static final Logger logger = LogManager.getLogger(CustomUserDetailsService.class);
private @Autowired CredentialsServiceQuery credentials;
private @Autowired MemberProfile memberProfile;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User.UserBuilder builder = null;
try {
boolean exists = credentials.checkUserExists(username);
if (exists) {
memberProfile = credentials.getUserInformation(username);
builder = User.withUsername(username);
builder.password(memberProfile.getPassword());
builder.authorities(getGrantedAuthorities());
logger.info("User exists: {}", username);
} else {
throw new UsernameNotFoundException(SpringSecurityMessageSource.getAccessor().getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", new Object[] {username}, "User credentials is wrong"));
}
} catch (Exception ex) {
throw new UsernameNotFoundException(SpringSecurityMessageSource.getAccessor().getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", new Object[] {username}, "User credentials is wrong"));
//throw new UsernameNotFoundException("An error occured while trying to find the username, " + username, ex);
}
return builder.build();
}
private List<GrantedAuthority> getGrantedAuthorities(){
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.clear();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return authorities;
}
}
我的安全配置有必要的方法调用:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().httpBasic().and().cors().and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and().exceptionHandling()
.authenticationEntryPoint(entryPoint);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/",
"/swagger-ui.html",
"/webjars/**",
"/swagger-resources/**",
"/v2/api-docs",
"/info");
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
UrlBasedCorsConfigurationSource source = new
UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration.applyPermitDefaultValues());
return source;
}
public AuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider impl = new DaoAuthenticationProvider();
impl.setUserDetailsService(userDetailsService);
impl.setPasswordEncoder(passwordEncoder);
impl.setHideUserNotFoundExceptions(false);
return impl;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
最后,我的入口点:
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex) throws IOException, ServletException {
String json = String.format("{\"errorcode\": \"%s\", \"message\": \"%s\"}", response.getStatus(), ex.getMessage());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
}
我了解,在这种情况下,入口点负责编写在调用我的 Web 服务时提供错误凭据时传递的错误消息。所以我的问题是如何让入口点传递自定义消息,例如“用户 A 的帐户已锁定”?
如果入口点做不到,还有什么我可以做的吗?
【问题讨论】:
标签: java spring-boot spring-security