java - Spring security switch to Ldap authentication and database authorities -
i implemented database authentication web page , web service. work both, have add ldap authentication. have authenticate through remote ldap server (using username , password) , if user exists have use database user roles (in database username same username of ldap). have switch actual code ldap , database authentication above explained. code is: securityconfig class
@configuration @enablewebsecurity @enableglobalmethodsecurity(securedenabled = true, prepostenabled = true, proxytargetclass = true) public class securityconfig extends websecurityconfigureradapter { @autowired @qualifier("userdetailsservice") userdetailsservice userdetailsservice; @autowired public void configureglobal(authenticationmanagerbuilder auth) throws exception { auth.userdetailsservice(userdetailsservice).passwordencoder(passwordencoder()); } @bean public passwordencoder passwordencoder(){ passwordencoder encoder = new bcryptpasswordencoder(); return encoder; } @configuration @order(1) public static class apiwebsecurityconfig extends websecurityconfigureradapter{ @override protected void configure(httpsecurity http) throws exception { http.csrf().disable() .antmatcher("/client/**") .authorizerequests() .anyrequest().authenticated() .and() .httpbasic(); } } @configuration @order(2) public static class formwebsecurityconfig extends websecurityconfigureradapter{ @override public void configure(websecurity web) throws exception { web //spring security ignores request static resources such css or js files. .ignoring() .antmatchers("/static/**"); } @override protected void configure(httpsecurity http) throws exception { http .authorizerequests() //authorize request configuration //the / , /register path accepted without login //.antmatchers("/", "/register").permitall() //the /acquisition/** need admin role //.antmatchers("/acquisition/**").hasrole("admin") //.and().exceptionhandling().accessdeniedpage("/access_denied"); //all path need authentication .anyrequest().authenticated() .and() //login form configuration others .formlogin() .loginpage("/login") //important because otherwise goes in loop because login page require authentication , authentication require login page .permitall() .and() .logout() .logoutsuccessurl("/login?logout") .permitall(); // csrf tokens handling } }
myuserdetailsservice class
@service("userdetailsservice") public class myuserdetailsservice implements userdetailsservice { @autowired private userservices userservices; static final logger log = loggerfactory.getlogger(myuserdetailsservice.class); @transactional(readonly=true) @override public userdetails loaduserbyusername(final string username){ try{ com.domain.user user = userservices.findbyid(username); if (user==null) log.error("threw exception in myuserdetailsservice::loaduserbyusername : user doesn't exist" ); else{ list<grantedauthority> authorities = builduserauthority(user.getuserrole()); return builduserforauthentication(user, authorities); } }catch(exception e){ log.error("threw exception in myuserdetailsservice::loaduserbyusername : " + errorexceptionbuilder.builderrorresponse(e)); } return null; } // converts com.users.model.user user // org.springframework.security.core.userdetails.user private user builduserforauthentication(com.domain.user user, list<grantedauthority> authorities) { return new user(user.getusername(), user.getpassword(), user.isenabled(), true, true, true, authorities); } private list<grantedauthority> builduserauthority(set<userrole> userroles) { set<grantedauthority> setauths = new hashset<grantedauthority>(); // build user's authorities (userrole userrole : userroles) { setauths.add(new simplegrantedauthority(userrole.getuserrolekeys().getrole())); } list<grantedauthority> result = new arraylist<grantedauthority>(setauths); return result; }
so have to:
1)access of user login page web pages , username , password web services. has done through ldap.
2)the username of user needs database query authenticate user. have idea how can implement this? thanks
update right code: following @m. deinum advice create myauthoritiespopulator
class instead of myuserdetailsservice
, authentication database , ldap works:
@service("myauthpopulator") public class myauthoritiespopulator implements ldapauthoritiespopulator { @autowired private userservices userservices; static final logger log = loggerfactory.getlogger(myauthoritiespopulator.class); @transactional(readonly=true) @override public collection<? extends grantedauthority> getgrantedauthorities(dircontextoperations userdata, string username) { set<grantedauthority> authorities = new hashset<grantedauthority>(); try{ com.domain.user user = userservices.findbyid(username); if (user==null) log.error("threw exception in myauthoritiespopulator::getgrantedauthorities : user doesn't exist ats database" ); else{ for(userrole userrole : user.getuserrole()) { authorities.add(new simplegrantedauthority(userrole.getuserrolekeys().getrole())); } return authorities; } }catch(exception e){ log.error("threw exception in myauthoritiespopulator::getgrantedauthorities : " + errorexceptionbuilder.builderrorresponse(e)); } return authorities; } }
and changed securityconfig below:
@configuration @enablewebsecurity @enableglobalmethodsecurity(securedenabled = true, prepostenabled = true, proxytargetclass = true) public class securityconfig extends websecurityconfigureradapter { @autowired @qualifier("myauthpopulator") ldapauthoritiespopulator myauthpopulator; @autowired public void configureglobal(authenticationmanagerbuilder auth) throws exception { auth.ldapauthentication() .contextsource() .url("ldap://127.0.0.1:10389/dc=example,dc=com") // .managerdn("") // .managerpassword("") .and() .usersearchbase("ou=people") .usersearchfilter("(uid={0})") .ldapauthoritiespopulator(myauthpopulator); } @configuration @order(1) public static class apiwebsecurityconfig extends websecurityconfigureradapter{ @override protected void configure(httpsecurity http) throws exception { http.csrf().disable() .antmatcher("/client/**") .authorizerequests() //excluede send file authentication because doesn't work spring authentication //todo add java authentication send method .antmatchers(httpmethod.post, "/client/file").permitall() .anyrequest().authenticated() .and() .httpbasic(); } } @configuration @order(2) public static class formwebsecurityconfig extends websecurityconfigureradapter{ @override public void configure(websecurity web) throws exception { web //spring security ignores request static resources such css or js files. .ignoring() .antmatchers("/static/**"); } @override protected void configure(httpsecurity http) throws exception { http .authorizerequests() //authorize request configuration //the "/" , "/register" path accepted without login //.antmatchers("/", "/register").permitall() //the /acquisition/** need admin role //.antmatchers("/acquisition/**").hasrole("admin") //.and().exceptionhandling().accessdeniedpage("/access_denied"); //all path need authentication .anyrequest().authenticated() .and() //login form configuration others .formlogin() .loginpage("/login") //important because otherwise goes in loop because login page require authentication , authentication require login page .permitall() .and() .logout() .logoutsuccessurl("/login?logout") .permitall(); } } }
my ldap development environment created in apache directory studio
spring security supports ldap out-of-the-box. has whole chapter on this.
to use , configure ldap add spring-security-ldap
dependency , next use authenticationmanagerbuilder.ldapauthentication
configure it. ldapauthenticationproviderconfigurer
allows set needed things up.
@autowired public void configureglobal(authenticationmanagerbuilder auth) throws exception { auth.ldapauthentication() .contextsource() .url(...) .port(...) .managerdn(...) .managerpassword(...) .and() .passwordencoder(passwordencoder()) .usersearchbase(...) .ldapauthoritiespopulator(new userserviceldapauthoritiespopulater(this.userservice)); }
something (it should give @ least idea on what/how configure things) there more options check javadocs that. if cannot use userservice
retrieve roles (because roles in database) implement own ldapauthoritiespopulator
that.
Comments
Post a Comment