此问题实际上与此问题有关problem。
根据@ harsh-poddar的建议,我相应地添加了过滤器。
然而,在添加之后,即使使用有效的凭据,我似乎也无法登录。
以下是相关代码:
SecurityConfig
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// @Bean
// public CustomAuthenticationEntryPoint customAuthenticationEntryPoint() {
// return new CustomAuthenticationEntryPoint();
// }
@Bean
public CustomExceptionTranslationFilter customExceptionTranslationFilter() {
return new CustomExceptionTranslationFilter(new CustomAuthenticationEntryPoint());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//Note : Able to login without this filter, but after adding this, valid credential also fails
.addFilterAfter(customExceptionTranslationFilter(), ExceptionTranslationFilter.class)
// .exceptionHandling()
// .authenticationEntryPoint(new customAuthenticationEntryPoint())
// .and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.requestCache()
.requestCache(new NullRequestCache())
.and()
.httpBasic()
.and()
.csrf().disable();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new CustomAuthenticationProvider());
}
}
CustomAuthenticationProvider
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
public CustomAuthenticationProvider() {
super();
}
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
final String name = authentication.getName();
final String password = authentication.getCredentials().toString();
if (name.equals("admin") && password.equals("password")) {
final List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
final UserDetails principal = new User(name, password, grantedAuths);
final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);
return auth;
} else {
throw new BadCredentialsException("NOT_AUTHORIZED");
}
}
@Override
public boolean supports(final Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
CustomExceptionTranslationFilter
@Component
public class CustomExceptionTranslationFilter extends ExceptionTranslationFilter {
public CustomExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint) {
super(authenticationEntryPoint);
}
}
CustomAuthenticationEntryPoint
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized.");
}
}
p / s:对不起基本问题,我在春天真的很新。春天安全。
答案 0 :(得分:3)
AuthenticationEntryPoint
的预期设计是启动/启动身份验证。但是,您的实施CustomAuthenticationEntryPoint
不会这样做。相反,它只是发回未经授权的响应。有关实现细节的更多详细信息,请参阅AuthenticationEntryPoint的javadoc。
根据您的配置,您使用HTTP Basic进行身份验证:
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
此特定配置将自动配置BasicAuthenticationEntryPoint
,这是AuthenticationEntryPoint
的实现。 BasicAuthenticationEntryPoint
将根据server protocol向http {1}}的http响应标头提出质询,以进行身份验证。
但是,您正在配置自己的WWW-Authenticate: Basic realm="User Realm"
,它最终会覆盖CustomAuthenticationEntryPoint
,这不是您想要做的。
other post建议使用此配置,这不再是您想要做的。
BasicAuthenticationEntryPoint
如果您的主要目标是在身份验证失败时向用户提供自定义响应,那么我建议使用已配置protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint());
}
的表单登录配置。这是配置:
AuthenticationFailureHandler
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().failureHandler(new DefaultAuthenticationFailureHandler())
.and()
.csrf().disable(); // NOTE: I would recommend enabling CSRF
的实施将是:
DefaultAuthenticationFailureHandler
AuthenticationFailureHandler专门用于处理失败的身份验证尝试。