grails.plugin.springsecurity.ldap.userdetails.GrailsLdapAuthoritiesPopulator.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-security-ldap Show documentation
Show all versions of spring-security-ldap Show documentation
Adds Spring Security LDAP support to a Grails application.
The newest version!
/* Copyright 2006-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package grails.plugin.springsecurity.ldap.userdetails
import grails.plugin.springsecurity.userdetails.GrailsUserDetailsService
import groovy.transform.CompileStatic
import org.springframework.beans.factory.InitializingBean
import org.springframework.ldap.core.ContextSource
import org.springframework.ldap.core.DirContextOperations
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator
import org.springframework.util.Assert
/**
* @author Burt Beckwith
*/
@CompileStatic
class GrailsLdapAuthoritiesPopulator extends DefaultLdapAuthoritiesPopulator implements InitializingBean {
/** Dependency injection for the user details service. */
GrailsUserDetailsService userDetailsService
/** Dependency injection for whether to retrieve roles from the database in addition to LDAP. */
Boolean retrieveDatabaseRoles
protected String roleStripPrefix
protected String roleStripSuffix
protected boolean roleConvertDashes = false
protected boolean roleToUpperCase = false
/**
* Constructor for group search scenarios. userRoleAttributes may still be
* set as a property.
*
* @param contextSource supplies the contexts used to search for user roles.
* @param groupSearchBase if this is an empty string the search will be performed from the root DN of the
* context factory.
*/
GrailsLdapAuthoritiesPopulator(ContextSource contextSource, String groupSearchBase) {
super(contextSource, groupSearchBase)
}
/**
* This cleans a role based on configuration flags set.
* @param role the role to clean
* @return the cleaned role
*/
GrantedAuthority cleanRole(GrantedAuthority role) {
if (!(role instanceof SimpleGrantedAuthority)) {
return role
}
SimpleGrantedAuthority newRole = (SimpleGrantedAuthority) role
if (roleConvertDashes && newRole.authority.contains('-')) {
// replace dashes
newRole = new SimpleGrantedAuthority(newRole.authority.replaceAll('-', '_'))
}
if (roleToUpperCase && newRole.authority.toUpperCase() != newRole.authority) {
// convert to upper case
newRole = new SimpleGrantedAuthority(newRole.authority.toUpperCase())
}
if (roleStripPrefix) {
// strip prefix if found
String tempPrefix = rolePrefix + roleStripPrefix
if (tempPrefix && newRole.authority.startsWith(tempPrefix) && newRole.authority.length() > tempPrefix.length()) {
// replace dashes
newRole = new SimpleGrantedAuthority(newRole.authority.replace(tempPrefix, rolePrefix).trim())
}
}
// strip suffix if found
if (roleStripSuffix && newRole.authority.length() > roleStripSuffix.length() &&
newRole.authority.endsWith(roleStripSuffix)) {
int roleLength = newRole.authority.length()
int suffixLength = roleStripSuffix.length()
newRole = new SimpleGrantedAuthority(
newRole.authority.substring(0, roleLength - suffixLength).trim())
}
if (newRole.authority.contains(' ')) {
// replace spaces
newRole = new SimpleGrantedAuthority(newRole.authority.replaceAll(' ', '_'))
}
while (newRole.authority.contains('__')) {
// replace __
newRole = new SimpleGrantedAuthority(newRole.authority.replaceAll('__', '_'))
}
return newRole
}
@Override
Set getGroupMembershipRoles(String userDn, String username) {
super.getGroupMembershipRoles(userDn, username).collect { cleanRole it } as Set
}
@Override
protected Set getAdditionalRoles(DirContextOperations user, String username) {
if (!retrieveDatabaseRoles) {
return null
}
try {
UserDetails dbDetails = userDetailsService.loadUserByUsername(username, true)
if (dbDetails.authorities) {
return new HashSet(dbDetails.authorities)
}
}
catch (UsernameNotFoundException ignored) {
// just looking for roles, so ignore the UsernameNotFoundException
}
}
/**
* Hooks to adjust prefix string if other cleaning flags are set
*/
protected void updateRoleStripPrefix() {
// convert dashes
if (roleConvertDashes && roleStripPrefix?.contains('-')) {
roleStripPrefix = roleStripPrefix.replaceAll('-', '_')
}
// To upper case
if (roleToUpperCase && roleStripPrefix && roleStripPrefix.toUpperCase() != roleStripPrefix) {
roleStripPrefix = roleStripPrefix.toUpperCase()
}
}
/**
* Hooks to adjust suffix string if other cleaning flags are set
*/
protected void updateRoleStripSuffix() {
// convert dashes
if (roleConvertDashes && roleStripSuffix?.contains('-')) {
roleStripSuffix = roleStripSuffix.replaceAll('-', '_')
}
// To upper case
if (roleToUpperCase && roleStripSuffix && roleStripSuffix.toUpperCase() != roleStripSuffix) {
roleStripSuffix = roleStripSuffix.toUpperCase()
}
}
/**
* Dependency injection for whether or not to remove a prefix string from a LDAP
* group name if it matches the beginning of the group name, but not the full
* name of the group.
* @param prefix if not null, this is stripped from the group name before it is made into a role
*/
void setRoleStripPrefix(String prefix) {
roleStripPrefix = prefix
updateRoleStripPrefix()
}
/**
* Dependency injection for whether or not to remove a suffix string from a LDAP
* group name if it matches the end of the group name, but not the full
* name of the group.
* @param suffix if not null, this is stripped from the group name before it is made into a role
*/
void setRoleStripSuffix(String suffix) {
roleStripSuffix = suffix
updateRoleStripSuffix()
}
/**
* Dependency injection for whether or not to convert all dashes to underscores if found in a
* group name before it is made into a role.
* @param convertDashes if true
, all dashes are converted to underscores
*/
void setRoleConvertDashes(boolean convertDashes) {
roleConvertDashes = convertDashes
updateRoleStripPrefix()
updateRoleStripSuffix()
}
/**
* Dependency injection for whether or not to convert group names to uppercase before they
* are made into roles.
* @param toUpperCase if true
, roles are converted to uppercase
*/
void setRoleToUpperCase(boolean toUpperCase) {
roleToUpperCase = toUpperCase
updateRoleStripPrefix()
updateRoleStripSuffix()
}
void afterPropertiesSet() {
Assert.notNull userDetailsService, 'userDetailsService must be specified'
Assert.notNull retrieveDatabaseRoles, 'retrieveDatabaseRoles must be specified'
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy