简体   繁体   中英

Spring security programmatic in-memory UserDetailsService: username and roles, NO password

UPDATE: I was not able to solve the problem presented here, but the simplest and most effective solution to my problem was to NOT use the in-memory userDetailsService. Details of my resulting solution are in a follow-up post.


SUMMARY

With the old SpringSecurity.xml I never needed to provide the password to support additional ROLEs via the in-memory userDetailsService. It was very convenient, especially during the development phase.

With the programmatic approach it is easy to provide username+password+roles, but it is not clear how to provide only username+roles. I would like to learn how.

EXAMPLES

In the examples below "user" does authentication and authorization in Active Directory through adAuthProvider. The programmatic examples are the full content of the SecurityConfig configure(AuthenticationManagerBuilder auth) method.

security.xml: (this worked for years, what I want to replicate)

  <sec:user-service id="xmlUserDetailsService">
    <sec:user name="user" authorities="ROLE_USER" />
  </sec:user-service>

Failed programmatic attempt: (direct translation of the above, notice that "user" does not setup the password... like in the XML above). Throws during server start: (org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor)

  auth.authenticationProvider(adAuthProvider);
  auth.inMemoryAuthentication()
  .passwordEncoder(passwordEncoder)
  .withUser("user").roles("USER")

Successful, adding the password for "user": (exception goes away)

  auth.authenticationProvider(adAuthProvider);
  auth.inMemoryAuthentication()
  .passwordEncoder(passwordEncoder)
  .withUser("user").password(passwordEncoder.encode("user")).roles("USER")

QUESTION:

  1. I assume that XML and programmatic configurations are supposed to be equivalent. Thus I assume there is a way to avoid supplying the password to the in-memory userDetails. Is this correct?
  2. Assuming the above is true, how do I do it? Could you please provide an example for the whole method?

I realize this is probably a trivial question. I googled and reviewed easily 100 examples, but they all include the password. Not a single one showed how to use in-memory just for authorization - relying on the Active Directory authentication provider to validate the password.

I hope the following helps the next googler with my problem.

First, my thanks to Deinum, he got me thinking in the right direction.

Just adding using a dummy password in the code of the original post did not work, but this worked even better for my needs:

  • I was already using a custom AuthenticationProvider . It was easy to place and read the extra roles for users from a value in the property file with the JSON syntax: springsecurity.extraRoles=[{"username":"usernameValue", "roles":["ROLE_XTRA1", "ROLE_XTRA2"]}] .
  • The extra roles rarely change, so they get read into a static Map, and are added to the user roles retrieved from AD as part of the authenticate() process.
  • And since I already had the property deploy.environment=DEV , I used it to disable the mechanism in PROD. A safety.net against deployment mistakes.

This description should be sufficient, but let me know if anyone needs a more detailed explanation of any of the steps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM