I am using loadUserByUsername method to authenticate user, however, I need to validate against allowed ip addresses as well.
But when I am trying
SecurityContextHolder.getContext().getAuthentication();
getting null.
Please advice, how I can access users client ip address while authenticating user.
To solve your problem you should implement custom authentication provider (that can be based on DaoAuthenticationProvider
or can be implemented from scratch, etc). This authentication provider should be registered in Authentication manager providers set. Also, this provider will have autowired HttpServletRequest
type property, related to context http request. Then, when you performing client authenticationv via that provider, you can obtain user IP address by invoking HttpServletRequest.getRemoteAddr()
.
Code:
/**
* IP address based authentication provider
*/
@Service
public class IPAddressBasedAuthenticationProvider extends AuthenticationProvider {
/**
* Context http request
*/
@Autowired
private HttpServletRequest request;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String ipAddress = request.getRemoteAddr();
//do authentication specific stuff (accessing users table in database, etc.)
//return created authentication object (if user provided valid credentials)
}
}
Configuration:
<security:http auto-config="true" authentication-manager-ref="authenticationManager" use-expressions="true"/>
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<constructor-arg name="providers">
<list>
<ref bean="iPAddressBasedAuthenticationProvider"/>
</list>
</constructor-arg>
</bean>
Also, you can add other authentication providers (if you need to). Hope this helps. Links: AuthenticationProvider ProviderManager
/**
* IP address based authentication provider
*/
@Service
public class IPAddressBasedAuthenticationProvider extends AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
final WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails();
details.getRemoteAddress();
}
}
You are implementing UserDetailsService's loadUserByUsername method.
As per documentation There is often some confusion about UserDetailsService. It is purely a DAO for user data and performs no other function other than to supply that data to other components within the framework. In particular, it does not authenticate the user, which is done by the AuthenticationManager. In many cases it makes more sense to implement AuthenticationProvider directly if you require a custom authentication process.
UserDetails userDetails= customUserDetailsService.loadUserByUsername("name");
this will give a userDetails object.You can do all authority related code in loadUserByUsername().If you would like to manually set an authenticated user in Spring Security.follow the code
Authentication authentication= new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()) ;
SecurityContextHolder.getContext().setAuthentication(authentication);
You will get IP address from request header.
How can I retrieve IP address from HTTP header in Java
you can do that somewhere in spring security filterchain.
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