具有LDAP身份验证的自定义权(Custom authorities with LDAP authentication)

编程入门 行业动态 更新时间:2024-10-28 04:18:57
具有LDAP身份验证的自定义权(Custom authorities with LDAP authentication)

我发现很少有Spring XML配置示例用于使用LDAP登录并使用自定义方法而不是通过LDAP配置登录用户的权限。 不幸的是,我找不到任何带注释的Spring Boot示例。

在我们的示例中,有一个中央LDAP存储库,其中存储了用户的用户名和密码,但用户的组不存储在那里。

我感谢任何例子或参考。 先谢谢你。

I’ve found few Spring XML Configuration examples for logging in with LDAP and configuring the authorities of the logged in user with the help of a custom method and not through LDAP. Unfortunately, I could not find any Spring Boot example with annotations.

In our case, there is a central LDAP repository in which the usernames and passwords of the users are stored, but the groups of the users are not stored there.

I appreciate any example or reference. Thank you in advance.

最满意答案

您可以在下面找到我们在项目中的最终实施。 基本流程是:

a)在身份验证期间检查用户ID和角色。 如果未定义用户或没有应用程序的角色,请不要对用户进行身份验证。

b)如果用户通过数据库检查,继续使用ldap身份验证。

c)将来自数据库的角色与在应用程序期间使用的ldap合并。

public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter implements InitializingBean { ... @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .authenticationProvider(this.ldapAndDatabaseAuthenticationProvider()); } @Bean(name="ldapAuthenticationProvider") public AuthenticationProvider ldapAndDatabaseAuthenticationProvider(){ LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper(); userDetailsMapper.setRoleAttributes(new String[]{"groupMembership"}); LdapAndDatabaseAuthenticationProvider provider = new LdapAndDatabaseAuthenticationProvider(this.ldapAuthenticator(), this.ldapAuthoritiesPopulator()); provider.setUserDetailsContextMapper(userDetailsMapper); return provider; } @Bean( name = "ldapAuthoritiesPopulator" ) public LdapAndDatabaseAuthoritiesPopulator ldapAuthoritiesPopulator(){ return new LdapAndDatabaseAuthoritiesPopulator(this.contextSource(), ""); } @Bean( name = "ldapAuthenticator" ) public LdapAuthenticator ldapAuthenticator() { BindAuthenticator authenticator = new BindAuthenticator( this.contextSource() ); authenticator.setUserDnPatterns(new String[]{"cn={0},ou=prod,o=COMP"}); return authenticator; } @Bean( name = "contextSource" ) public DefaultSpringSecurityContextSource contextSource() { DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource( ldapUrl ); return contextSource; }

以下是其他角色populator(LdapAndDatabaseAuthoritiesPopulator)的实现方式。

public class LdapAndDatabaseAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator{ public LdapAndDatabaseAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase) { super(contextSource, groupSearchBase); } protected Set<GrantedAuthority> getAdditionalRoles(DirContextOperations user, String username) { Set<GrantedAuthority> mappedAuthorities = new HashSet<GrantedAuthority>(); /* Add additional roles from other sources for this user*/ /* below add is just an example of how to add a role */ mappedAuthorities.add( new GrantedAuthority() { private static final long serialVersionUID = 3618700057662135367L; @Override public String getAuthority() { return "ROLE_MYAPP_USER"; //this is just a temporary role we are adding as example. get the roles from database. } @Override public String toString(){ return this.getAuthority(); } }); for (GrantedAuthority granted : mappedAuthorities) { log.debug("Authority : {}", granted.getAuthority().toString()); } return mappedAuthorities; } }

下面是Custom Ldap身份验证提供程序(LdapAndDatabaseAuthenticationProvider)实现的方式,用于检查用户是否具有在数据库中定义的访问应用程序所需的角色。 如果用户不在数据库中或缺少角色,则身份验证将抛出帐户DisabledException。

franDays还建议使用“自定义身份验证提供程序”。 我想给他一个功劳。

public class LdapAndDatabaseAuthenticationProvider extends LdapAuthenticationProvider{ public LdapAndDatabaseAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) { super(authenticator, authoritiesPopulator); } @Override protected DirContextOperations doAuthentication( UsernamePasswordAuthenticationToken authentication) { log.debug("Checking if user <{}> is defined at database to use this application.", authentication.getName()); // Here is the part we need to check in the database if user has required role to log into the application. // After check if user has the role, do nothing, otherwise throw exception like below example. boolean canUserAuthenticate = isActiveUserExist(authentication.getName()); log.debug("canUserAuthenticate: {}", canUserAuthenticate); if (!canUserAuthenticate) throw new DisabledException("User does not have access to Application!"); return super.doAuthentication(authentication); } private boolean isActiveUserExist(String userId) { // Do your logic here are return boolean value... }

Below you can find our final implementation at the project. Basic flow is:

a)Check the user id and roles during the authentication. If user is not defined or does not have the roles for the application, do not authenticate the user.

b)if user pass the database check, continue with ldap authentication.

c)Merge the roles coming from database with ldap to be used during the application.

public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter implements InitializingBean { ... @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .authenticationProvider(this.ldapAndDatabaseAuthenticationProvider()); } @Bean(name="ldapAuthenticationProvider") public AuthenticationProvider ldapAndDatabaseAuthenticationProvider(){ LdapUserDetailsMapper userDetailsMapper = new LdapUserDetailsMapper(); userDetailsMapper.setRoleAttributes(new String[]{"groupMembership"}); LdapAndDatabaseAuthenticationProvider provider = new LdapAndDatabaseAuthenticationProvider(this.ldapAuthenticator(), this.ldapAuthoritiesPopulator()); provider.setUserDetailsContextMapper(userDetailsMapper); return provider; } @Bean( name = "ldapAuthoritiesPopulator" ) public LdapAndDatabaseAuthoritiesPopulator ldapAuthoritiesPopulator(){ return new LdapAndDatabaseAuthoritiesPopulator(this.contextSource(), ""); } @Bean( name = "ldapAuthenticator" ) public LdapAuthenticator ldapAuthenticator() { BindAuthenticator authenticator = new BindAuthenticator( this.contextSource() ); authenticator.setUserDnPatterns(new String[]{"cn={0},ou=prod,o=COMP"}); return authenticator; } @Bean( name = "contextSource" ) public DefaultSpringSecurityContextSource contextSource() { DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource( ldapUrl ); return contextSource; }

Here is how additional roles populator (LdapAndDatabaseAuthoritiesPopulator ) implemented.

public class LdapAndDatabaseAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator{ public LdapAndDatabaseAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase) { super(contextSource, groupSearchBase); } protected Set<GrantedAuthority> getAdditionalRoles(DirContextOperations user, String username) { Set<GrantedAuthority> mappedAuthorities = new HashSet<GrantedAuthority>(); /* Add additional roles from other sources for this user*/ /* below add is just an example of how to add a role */ mappedAuthorities.add( new GrantedAuthority() { private static final long serialVersionUID = 3618700057662135367L; @Override public String getAuthority() { return "ROLE_MYAPP_USER"; //this is just a temporary role we are adding as example. get the roles from database. } @Override public String toString(){ return this.getAuthority(); } }); for (GrantedAuthority granted : mappedAuthorities) { log.debug("Authority : {}", granted.getAuthority().toString()); } return mappedAuthorities; } }

Below is how the Custom Ldap authentication provider (LdapAndDatabaseAuthenticationProvider) implemented to check if user has required roles defined in the database to access the application. If user is not in the database or roles are missing, authentication will throw account DisabledException.

franDays also suggested to use "Custom Authentication Provider". I would like to give him a credit.

public class LdapAndDatabaseAuthenticationProvider extends LdapAuthenticationProvider{ public LdapAndDatabaseAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) { super(authenticator, authoritiesPopulator); } @Override protected DirContextOperations doAuthentication( UsernamePasswordAuthenticationToken authentication) { log.debug("Checking if user <{}> is defined at database to use this application.", authentication.getName()); // Here is the part we need to check in the database if user has required role to log into the application. // After check if user has the role, do nothing, otherwise throw exception like below example. boolean canUserAuthenticate = isActiveUserExist(authentication.getName()); log.debug("canUserAuthenticate: {}", canUserAuthenticate); if (!canUserAuthenticate) throw new DisabledException("User does not have access to Application!"); return super.doAuthentication(authentication); } private boolean isActiveUserExist(String userId) { // Do your logic here are return boolean value... }

更多推荐

本文发布于:2023-08-06 12:19:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1448498.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   身份验证   LDAP   authentication   authorities

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!