10

I'm working on a java spring mvc application. I have implemented the UserDetailsService interface like this:

@Component
@Transactional
public class SecurityDAO implements UserDetailsService{

     @Override
     public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
         ...
     }

     ....
}

I need to find the user login url inside loadUserByUsername method(because the project has multiple login urls). In fact, I want to access request parameters inside UserDetailsService implementation.

hamed
  • 7,939
  • 15
  • 60
  • 114

4 Answers4

12

Just inject the request on your service:

 @Autowired
 private HttpServletRequest request;

For it to work you need to register RequestContextListener previously, though:

@Bean 
public RequestContextListener requestContextListener(){
    return new RequestContextListener();
} 
dambros
  • 4,252
  • 1
  • 23
  • 39
8

All the information is available through HttpServletRequest. You can obtain it by:

Dependency injection

The easiest way would be to inject servlet request directly into your UserDetailsService: class:

public MyDetailsService implements UserDetailsService {

  @Autowired
  private HttpServletRequest request;

  //...

}

or

public MyDetailsService implements UserDetailsService {

  @Autowired
  private HttpServletRequest request;

    public UserDetails loadUserByUsername(String username){
                HttpServletRequest request  =
             ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes())
                    .getRequest();
    }

}

Remember to add the following listener to your web.xml if you are not spring boot:

<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>

If you are using spring boot, add below this.

@Bean 
public RequestContextListener requestContextListener(){
    return new RequestContextListener();
}

UPDATE: This works because Spring injects special scoped proxy implementing HttpServletRequest, so you are able to access request-scoped request "bean" from singleton-scoped MyDetailsService. Under the hood every call to request's parameters is routed to org.springframework.web.context.request.RequestContextHolder#requestAttributesHolder ThreadLocal which you can also access directly. As you can see Spring is very flexible when it comes to scoping rules. It just works.

RequestContextHolder

Another approach is to use RequestContextHolder:

HttpServletRequest request = 
  ((ServletRequestAttributes) RequestContextHolder.
    currentRequestAttributes()).
    getRequest();

Further reading:

Community
  • 1
  • 1
Sudhakar
  • 3,104
  • 2
  • 27
  • 36
4

Simple way: 1) register RequestContextListener

@Bean
public RequestContextListener requestContextListener(){
return new RequestContextListener();
}

2) And to main class:

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.
currentRequestAttributes()).
getRequest();

3) After that we can take params in custom headers:

request.getHeader("OrganizationId")
0

You can get the current request with

HttpServletRequest request  =
 ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes())
        .getRequest();

ans then access the request params from there.

Dirk Lachowski
  • 3,121
  • 4
  • 40
  • 66