Apache Shiro 配置 LDAP 验证
通常在根据LDAP进行身份验证时一般进行以下三步:
- 利用一个LDAP用户的用户名和密码绑定到LDAP服务器。
- 在LDAP中检索一个用户的条目,然后将提供的密码和检索到的LDAP记录中进行验证。
- 根据LDAP提供的记录,再去本系统中查找授权信息。
Shiro 提供了DefaultLdapRealm
,只做了第二步,根据用户的条目和密码来验证。并不能满足我们的需求,所以肯定是要定制化LdapRealm。
这里使用Spring Ldap 来简化Ldap操作
public class LdapRealm extends AuthorizingRealm { private static final Logger logger = LoggerFactory.getLogger(LdapRealm.class); private LdapTemplate ldapTemplate; @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired private MenuService menuService; @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); String password = new String((char[]) token.getCredentials()); try { LdapQuery ldapQuery = LdapQueryBuilder.query().base("DC=example,DC=com").searchScope(SearchScope.SUBTREE) .filter("(sAMAccountName={0})", username); boolean authResult = ldapTemplate.authenticate(ldapQuery.base(), ldapQuery.filter().encode(), password); if (!authResult) { logger.debug("ldap authentication for {} failed", username); return null; } User ldapUser = (User) ldapTemplate.searchForObject(ldapQuery, new LdapUserAttrMapper()); User user = userService.selectUserById(ldapUser.getUserId()); if (user == null) { // 用户名不存在抛出异常 throw new UnknownAccountException(); } if (user.getRemoveFlag()) { // 用户被管理员锁定抛出异常 throw new LockedAccountException(); } SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, token.getCredentials(), "LdapRealm"); return authenticationInfo; } catch (Exception e) { logger.error("ldap authentication failed", e.toString()); return null; } } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { Long userId = ShiroUtils.getUserId(); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 角色加入AuthorizationInfo认证对象 info.setRoles(roleService.selectRoleKeys(userId)); // 权限加入AuthorizationInfo认证对象 info.setStringPermissions(menuService.selectPermsByUserId(userId)); return info; } public LdapTemplate getLdapTemplate() { return ldapTemplate; } public void setLdapTemplate(LdapTemplate ldapTemplate) { this.ldapTemplate = ldapTemplate; } }
关键的代码如下,验证用户和获取LDAP用户信息
LdapQuery ldapQuery = LdapQueryBuilder.query().base("DC=example,DC=com").searchScope(SearchScope.SUBTREE) .filter("(sAMAccountName={0})", username); boolean authResult = ldapTemplate.authenticate(ldapQuery.base(), ldapQuery.filter().encode(), password); User ldapUser = (User) ldapTemplate.searchForObject(ldapQuery, new LdapUserAttrMapper());
Spring 的 ldap 配置如下:
<bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource"> <property name="url" value="ldap://192.168.100.1:3268"/> <property name="userDn" value="CN=Reader"/> <property name="password" value="secret"/> </bean> <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"> <property name="contextSource" ref="ldapContextSource"/> </bean> <bean id="ldapRealm" class="com.example.shiro.LdapRealm"> <property name="ldapTemplate" ref="ldapTemplate"/> </bean>
相关推荐
Gexrior 2020-09-29
harddays 2020-06-25
80337960 2020-06-10
huaqiangli 2020-06-09
wenwst 2020-05-12
tomson 2020-03-27
wenwst 2020-02-25
SZStudy 2020-01-31
就是那个胖子 2019-12-18
蒜蓉粉丝蒸扇贝 2019-12-18
代码之源 2008-08-10
窃破天道 2019-11-04
milu 2011-08-09
81971834 2010-09-30
FiredFish 2009-09-04
BearStarX 2019-04-04
farwang 2010-11-07
WilliamLin 2010-04-16