[英]JHipster ldap Authentication
嘿,Overfloweens和JHipsters,我最近得出的結論是,我想嘗試將我的JHipster安全性與協議鏈接到ldap服務器,以驗證已經具有所有員工密碼和用戶名的工作目錄中的身份驗證。 但是,我想繼續使用JHipster的內置令牌系統,該系統使用Spring-mvc。 除了JHipster,我知道如何做ldap服務器,但是我不清楚如何修改SecurityConfiguration.java文件以實現這一點。 任何建議將不勝感激。
安全配置文件:
package com.comcast.castit.config;
import javax.inject.Inject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.springframework.security.web.authentication.RememberMeServices;
import com.comcast.castit.security.AjaxAuthenticationFailureHandler;
import com.comcast.castit.security.AjaxAuthenticationSuccessHandler;
import com.comcast.castit.security.AjaxLogoutSuccessHandler;
import com.comcast.castit.security.AuthoritiesConstants;
import com.comcast.castit.security.Http401UnauthorizedEntryPoint;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Inject
private Environment env;
@Inject
private AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler;
@Inject
private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler;
@Inject
private AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler;
@Inject
private Http401UnauthorizedEntryPoint authenticationEntryPoint;
@Inject
private UserDetailsService userDetailsService;
@Inject
private RememberMeServices rememberMeServices;
@Bean
public PasswordEncoder passwordEncoder() {
return new StandardPasswordEncoder();
}
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(
passwordEncoder());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/bower_components/**")
.antMatchers("/fonts/**").antMatchers("/images/**")
.antMatchers("/scripts/**").antMatchers("/styles/**")
.antMatchers("/views/**").antMatchers("/i18n/**")
.antMatchers("/swagger-ui/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint).and()
.rememberMe().rememberMeServices(rememberMeServices)
.key(env.getProperty("jhipster.security.rememberme.key")).and()
.formLogin().loginProcessingUrl("/app/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password").permitAll().and().logout()
.logoutUrl("/app/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID").permitAll().and().csrf().disable()
.headers().frameOptions().disable().authorizeRequests()
.antMatchers("/app/rest/register").permitAll()
.antMatchers("/app/rest/activate").permitAll()
.antMatchers("/app/rest/authenticate").permitAll()
.antMatchers("/app/rest/logs/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/app/**").authenticated()
.antMatchers("/metrics/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/health/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/dump/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/shutdown/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/beans/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/info/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/autoconfig/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/env/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api-docs/**")
.hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/protected/**").authenticated();
}
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
private static class GlobalSecurityConfiguration extends
GlobalMethodSecurityConfiguration {
}
}
默認身份驗證機制使用“ UserDetailsService”實現,在您的項目中應將其稱為“ com.comcast.castit.security.UserDetailsService”。
該代碼具有一個簡單的“ loadUserByUsername”,可根據用戶的登錄信息獲取該用戶並獲取其權限。
對於您的需求,您應該更改此部分->這不會影響應用程序的其余部分,這很好(Spring Security為此設計很好)
有一個關於將LDAP與Spring Security / Spring Boot結合使用的教程,您可以在這里查看: https : //spring.io/guides/gs/authenticating-ldap/
當然,如果我們有針對JHipster的特定文檔,那會更好,因此,如果您成功並有時間,將非常歡迎您提供反饋!
在SecurityConfiguration.java
將configureGlobal
函數更改為:
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
/*auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());*/
auth.ldapAuthentication()
.userSearchBase("ou=Users")
.userSearchFilter("(uid={0})")
.groupSearchBase("ou=Groups")
.groupSearchFilter("member={0}")
.contextSource()
.url("ldap://127.0.0.1:10389/o=myorganisation");
}
我已經注釋掉了之前的代碼。 然后,您的應用程序將通過ldap服務器進行身份驗證。 它仍然會在數據庫中檢查用戶詳細信息,如果用戶表中不存在該用戶,您將遇到諸如userRepository.findOneByLogin(login)
,該問題使用現有用戶名在數據庫中搜索用戶。
但是身份驗證將使用您的ldap憑據進行。
從SecurityConfig.java中刪除以下代碼片段
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return (AuthenticationManager) ldapAuthenticationManager;
}
然后創建一個LDAPAuthenticationManager類
package com.digitronic.isda.security;
import org.springframework.ldap.core.AuthenticationSource;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.authentication.BindAuthenticator;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
import org.springframework.stereotype.Component;
@Component("authenticationManagerBean")
public class LDAPAuthenticationManager implements AuthenticationManager {
LdapAuthenticationProvider provider = null;
@Override
public Authentication authenticate(Authentication arg0)
throws AuthenticationException {
return provider.authenticate(arg0);
}
LDAPAuthenticationManager() {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
"ldap://127.0.0.1:389");
contextSource.setUserDn("test.com\\Administrator");
contextSource.setCacheEnvironmentProperties(true);
try {
contextSource.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
contextSource.setPassword("asdasdasdjBj,K");
LdapContextSource ldapSrc = new LdapContextSource();
ldapSrc.setUrl("ldap://127.0.0.1:389");
ldapSrc.setUserDn("test.com\\Administrator");
ldapSrc.setPassword("asdasdasdjBj,K");
ldapSrc.setAnonymousReadOnly(false);
ldapSrc.setCacheEnvironmentProperties(true);
try {
ldapSrc.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
ldapSrc.setAuthenticationSource(new AuthenticationSource() {
@Override
public String getPrincipal() {
// TODO Auto-generated method stub
return "test.com\\Administrator";
}
@Override
public String getCredentials() {
// TODO Auto-generated method stub
return "asdasdasdjBj,K";
}
});
FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(
"cn=Users,dc=digitronic,dc=lan", "(sAMAccountName={0})",
ldapSrc);
BindAuthenticator bindAuth = new BindAuthenticator(contextSource);
bindAuth.setUserSearch(userSearch);
provider = new LdapAuthenticationProvider(bindAuth);
}
}
如果您需要UserDetailsContextMapper(對於授權機構),請添加以下內容:
provider.setUserDetailsContextMapper(new UserDetailsContextMapper() {
@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
// TODO Auto-generated method stub
}
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx,
String username,
Collection<? extends GrantedAuthority> authorities) {
User anwender = userRepository.findOneByAnwender(username);
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(
"ROLE_ADMIN");
grantedAuthorities.add(grantedAuthority);
return new org.springframework.security.core.userdetails.User(
username, "1", grantedAuthorities);
}
});
為了使用LDAP維護JHipster的內置令牌系統,我采取了另一種方法。 每當用戶嘗試登錄時,我都會在LDAP服務器中搜索其憑據,如果存在該憑據,則會在本地數據庫中創建一個具有LDAP屬性的新用戶,然后所有功能都會正常工作。
下列類僅用於獲取LDAP服務器的上下文和用戶屬性。
public class LDAPHelper {
private static LDAPHelper instance = null;
protected LDAPHelper() {
// Exists only to defeat instantiation
}
public static LDAPHelper getInstance() {
if (instance == null) {
instance = new LDAPHelper();
}
return instance;
}
public boolean validateLogin(String username, String password) {
return (getLdapContext(username, password) != null);
}
private LdapContext getLdapContext(String username, String password) {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put("com.sun.jndi.ldap.read.timeout", "120000");
env.put(Context.SECURITY_AUTHENTICATION, "Simple");
env.put(Context.SECURITY_PRINCIPAL, "VF-ROOT\\" + username);
env.put(Context.SECURITY_CREDENTIALS, password);
env.put(Context.PROVIDER_URL, "*ldap url*");
System.out.println(username);
try {
return new InitialLdapContext(env, null);
} catch (NamingException e) {
return null;
}
}
public User getUserAttributes(String username, String password)
throws NamingException { ... }
在AccountResource中,我更改了register方法以在LDAP服務器中搜索用戶,如果該用戶存在,則將其添加到本地數據庫(如果尚未添加)。 您在登錄之前調用此方法,以確保只有LDAP服務器中的用戶才能登錄您的應用程序。
@RequestMapping(value = "/register", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE,
MediaType.TEXT_PLAIN_VALUE })
@Timed
public ResponseEntity<?> registerAccount(@Valid @RequestBody ManagedUserDTO managedUserDTO,
HttpServletRequest request) {
HttpHeaders textPlainHeaders = new HttpHeaders();
textPlainHeaders.setContentType(MediaType.TEXT_PLAIN);
// user exists in LDAP server
if (LDAPHelper.getInstance().validateLogin(managedUserDTO.getLogin(), managedUserDTO.getPassword())) {
// user was already created in the local database
if (userRepository.findOneByLogin(managedUserDTO.getLogin().toLowerCase()).isPresent()) {
return new ResponseEntity<>("user exists in database", textPlainHeaders, HttpStatus.OK);
} else {
try {
User userAux = LDAPHelper.getInstance().getUserAttributes(managedUserDTO.getLogin(), managedUserDTO.getPassword());
User user = userService.createUserInformation(managedUserDTO.getLogin(), managedUserDTO.getPassword(), userAux.getFirstName(),
userAux.getLastName(), userAux.getEmail(), managedUserDTO.getLangKey());
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new ResponseEntity<>("user created in database", textPlainHeaders, HttpStatus.OK);
}
} else {
return new ResponseEntity<>("user does not exist in ldap", textPlainHeaders, HttpStatus.UNAUTHORIZED);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.