[英]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.