Solution. Review the existing Spring Security's authentication class, the “locked” feature is already implemented. To enable the limit login attempts, you need to set the UserDetails. isAccountNonLocked to false.
For adding a Spring Boot Security to your Spring Boot application, we need to add the Spring Boot Starter Security dependency in our build configuration file. Maven users can add the following dependency in the pom. xml file. Gradle users can add the following dependency in the build.
There's a number of ways to do this but the official way to do it is using a custom AuthenticationDetails
and AuthenticationDetailsSource
, subclassing Spring's WebAuthenticationDetails
and WebAuthenticationDetailsSource
, respectively. Add the extra field to the custom WebAuthenticationDetails
and have the custom WebAuthenticationDetailsSource
get the data from the request to populate the field.
In Spring Security 3.1 it's easy to configure by using the authentication-details-source-ref
attribute of the <form-login>
element.
In 3.0 you have to use a BeanPostProcessor
. There is an example in the Spring Security FAQ on using a BeanPostProcessor to configure a custom WebAuthenticationDetailsSource.
Once this is done then you can call SecurityContextHolder.getContext().getAuthentication().getDetails() to get access to your extra field.
Elaborating on @Vacuum's comment
Here's a simple way (untested, but I believe this would work)
ExUsernamePasswordAuthenticationFilter
that will extend the default filter and grab the additional parameter and store it in the session. It will look something like this:public class ExUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
final String dbValue = request.getParameter("dbParam");
request.getSession().setAttribute("dbValue", dbValue);
return super.attemptAuthentication(request, response);
}
}
UserDetailsService
implementation, modify your implementation of:UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;
to grab the session variable that the filter from step 1) makes available.
<http />
security set-up, override the default filter with your custom one<custom-filter ref="beanForYourCustomFilterFromStep1" position="FORM_LOGIN_FILTER"/>
Refer to this part of the documentation for more info about custom filters: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-custom-filters
sourcedelica mentioned using AuthenticationDetailsSource
and a custom AuthenticationDetails
.
Here is an example.
Add authentication-details-source-ref
attribute with the bean id customWebAuthenticationDetailsSource
to form-login
:
<security:http>
<security:intercept-url pattern="/**" access="..." />
<security:form-login authentication-details-source-ref="customWebAuthenticationDetailsSource" login-page="..." />
<security:logout logout-success-url="..." />
</security:http>
Create a new class CustomWebAuthenticationDetailsSource
:
package security;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import javax.servlet.http.HttpServletRequest;
public class CustomWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
@Override
public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
return new CustomWebAuthenticationDetails(context);
}
}
and the related CustomWebAuthenticationDetails
:
package security;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import javax.servlet.http.HttpServletRequest;
public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {
private final String yourParameter;
public CustomWebAuthenticationDetails(HttpServletRequest request) {
super(request);
yourParameter = request.getParameter("yourParameter");
}
public String getyourParameter() {
return yourParameter;
}
//TODO override hashCode, equals and toString to include yourParameter
@Override
public int hashCode() { /* collapsed */ }
@Override
public boolean equals(Object obj) { /* collapsed */ }
@Override
public String toString() { /* collapsed */ }
}
There is an easier way if you are using custom AuthenticationProvider
. You can just inject HttpServletRequest
and retrieve your extra parameter:
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired(required = false)
private HttpServletRequest request;
@Autowired
private MyAccountService myAccountService;
@Override
public Authentication authenticate(Authentication authentication) {
System.out.println("request testing= " + request.getParameter("testing"));
.....
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With