Question

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.

Was it helpful?

Solution

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

OTHER TIPS

/**
 * 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top