Reputation: 3535
I'm using DaoAuthenticationProvider
to provide authentication to my client requests. It is working fine in case the username/password combination is invalid it throws an AuthenticationException
with a message: Bad credentials
This is good and expected behavior, but I'm trying to have more friendly messages so i would like to replace it with an error message of my own.
I found that this message comes from
public SpringSecurityMessageSource() {
setBasename("org.springframework.security.messages");
}
//a bunch of authentication code
messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials","Bad credentials")
I tried to replace this message by creating a file
resources/org/springframework/security/messages.properties
and having its content as: AbstractUserDetailsAuthenticationProvider.badCredentials=anything else
but the bad message is still being thrown... what i am doing wrong? how to redefine default org.springframework.security.messages
Upvotes: 1
Views: 1337
Reputation: 11
Find Spring Security class, which messages you need to override, it will have such field:
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
This class also should implement MessageSourceAware
interface. This interface have only one method that you need to use: void setMessageSource(MessageSource messageSource)
For example I use DaoAuthenticationProvider
. It extends AbstractUserDetailsAuthenticationProvider
, that implements MessageSourceAware
.
From Spring Security source code:
public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
...
}
public abstract class AbstractUserDetailsAuthenticationProvider
implements AuthenticationProvider, InitializingBean, MessageSourceAware {
...
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
...
@Override
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
...
}
So, I'm overriding default DaoAuthenticationProvider
and set my message source.
My code:
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor // lombok
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final MessageSource messageSource;
private final UserDetailsService userDetailsService;
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages", "org/springframework/security/messages"); // my messages will override spring security messages, if message code the same
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService); // set my custom user details service
provider.setMessageSource(messageSource); // set my custom messages
return provider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider()); // set dao provider with my custom messages
}
}
My overriden messages /src/main/resources/messages.properties
:
AbstractUserDetailsAuthenticationProvider.disabled=Account is not activated. Please, activate your account. The activation link is sent in email
...etc...
All available codes for messages you can find here:
org.springframework.security:spring-security-core:[version]
/org/springframework/security/messages.properties
Upvotes: 1
Reputation: 173
Here's what you can try using AuthenticationEntryPoint
:
AuthenticationEntryPoint
then modify .write(..)
according to your desired format and message:public class MyEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Set your custom message here");
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(new MyEntryPoint());
}
Upvotes: 1