Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* Copyright 2006-2016 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
import grails.core.GrailsApplication
import grails.plugin.springsecurity.web.GrailsSecurityFilterChain
import grails.plugin.springsecurity.web.SecurityRequestHolder
import grails.util.Environment
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.apache.commons.lang.StringEscapeUtils
import org.springframework.context.ApplicationContext
import org.springframework.security.access.hierarchicalroles.RoleHierarchy
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.context.SecurityContext
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.core.userdetails.UserCache
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.web.WebAttributes
import org.springframework.security.web.authentication.switchuser.SwitchUserFilter
import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority
import org.springframework.security.web.savedrequest.SavedRequest
import org.springframework.util.StringUtils
import org.springframework.web.multipart.MultipartHttpServletRequest
import javax.servlet.Filter
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpSession
import static org.springframework.security.web.context.HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY
/**
* Helper methods.
*
* @author Burt Beckwith
*/
@CompileStatic
@Slf4j
final class SpringSecurityUtils {
private static final String MULTIPART_HTTP_SERVLET_REQUEST_KEY = MultipartHttpServletRequest.name
private static ConfigObject _securityConfig
private static GrailsApplication application
/** Ordered filter names. Plugins add or remove them, and can be overridden by config. */
static Map orderedFilters = [:]
/** Set by SpringSecurityCoreGrailsPlugin contains the actual filter beans in order. */
static SortedMap configuredOrderedFilters = new TreeMap()
/** Authentication provider names. Plugins add or remove them, and can be overridden by config. */
static List providerNames = []
/** Logout handler names. Plugins add or remove them, and can be overridden by config. */
static List logoutHandlerNames = []
/** AfterInvocationProvider names. Plugins add or remove them, and can be overridden by config. */
static List afterInvocationManagerProviderNames = []
/** Voter names. Plugins add or remove them and can be overridden by config. */
static List voterNames = []
// HttpSessionRequestCache.SAVED_REQUEST is package-scope
public static final String SAVED_REQUEST = 'SPRING_SECURITY_SAVED_REQUEST' // TODO use requestCache
// UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY is deprecated
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = 'SPRING_SECURITY_LAST_USERNAME'
// AbstractAuthenticationTargetUrlRequestHandler.DEFAULT_TARGET_PARAMETER was removed
public static final String DEFAULT_TARGET_PARAMETER = 'spring-security-redirect'
/** Default value for the name of the Ajax header. */
public static final String AJAX_HEADER = 'X-Requested-With'
/**
* Used to ensure that all authenticated users have at least one granted authority to work
* around Spring Security code that assumes at least one. By granting this non-authority,
* the user can't do anything but gets past the somewhat arbitrary restrictions.
*/
public static final String NO_ROLE = 'ROLE_NO_ROLES'
public static final String XML_HTTP_REQUEST = 'XMLHttpRequest'
public static final String FILTERS_NONE = 'none'
private SpringSecurityUtils() {
// static only
}
/**
* Set at startup by plugin.
* @param app the application
*/
static void setApplication(GrailsApplication app) {
application = app
initializeContext()
}
/**
* Extract the role names from authorities.
* @param authorities the authorities (a collection or array of {@link GrantedAuthority}).
* @return the names
*/
static Set authoritiesToRoles(authorities) {
Set roles = new HashSet()
for (authority in ReflectionUtils.asList(authorities)) {
String authorityName = ((GrantedAuthority)authority).authority
assert authorityName != null,
"Cannot process GrantedAuthority objects which return null from getAuthority() - attempting to process $authority"
roles << authorityName
}
roles
}
/**
* Get the current user's authorities.
* @return a list of authorities (empty if not authenticated).
*/
static Collection getPrincipalAuthorities() {
Authentication authentication = getAuthentication()
if (!authentication) {
return Collections.emptyList()
}
Collection extends GrantedAuthority> authorities = authentication.authorities
if (authorities == null) {
return Collections.emptyList()
}
// remove the fake role if it's there
Collection copy = ([] + authorities) as Collection
for (Iterator iter = copy.iterator(); iter.hasNext();) {
if (NO_ROLE == iter.next().authority) {
iter.remove()
}
}
copy
}
/**
* Split the role names and create {@link GrantedAuthority}s for each.
* @param roleNames comma-delimited role names
* @return authorities (possibly empty)
*/
static List parseAuthoritiesString(String roleNames) {
List requiredAuthorities = []
for (String auth in StringUtils.commaDelimitedListToStringArray(roleNames)) {
auth = auth.trim()
if (auth) {
requiredAuthorities << new SimpleGrantedAuthority(auth)
}
}
requiredAuthorities
}
/**
* Find authorities in granted that are also in required.
* @param granted the granted authorities (a collection or array of {@link GrantedAuthority}).
* @param required the required authorities (a collection or array of {@link GrantedAuthority}).
* @return the authority names
*/
static Set retainAll(granted, required) {
Set grantedRoles = authoritiesToRoles(granted)
grantedRoles.retainAll authoritiesToRoles(required)
grantedRoles
}
/**
* Check if the current user has all of the specified roles.
* @param roles a comma-delimited list of role names
* @return true if the user is authenticated and has all the roles
*/
static boolean ifAllGranted(String roles) {
ifAllGranted parseAuthoritiesString(roles)
}
static boolean ifAllGranted(Collection extends GrantedAuthority> roles) {
authoritiesToRoles(findInferredAuthorities(principalAuthorities)).containsAll authoritiesToRoles(roles)
}
/**
* Check if the current user has none of the specified roles.
* @param roles a comma-delimited list of role names
* @return true if the user is authenticated and has none the roles
*/
static boolean ifNotGranted(String roles) {
ifNotGranted parseAuthoritiesString(roles)
}
static boolean ifNotGranted(Collection extends GrantedAuthority> roles) {
!retainAll(findInferredAuthorities(principalAuthorities), roles)
}
/**
* Check if the current user has any of the specified roles.
* @param roles a comma-delimited list of role names
* @return true if the user is authenticated and has any the roles
*/
static boolean ifAnyGranted(String roles) {
ifAnyGranted parseAuthoritiesString(roles)
}
static boolean ifAnyGranted(Collection extends GrantedAuthority> roles) {
retainAll findInferredAuthorities(principalAuthorities), roles
}
/**
* Parse and load the security configuration.
* @return the configuration
*/
static synchronized ConfigObject getSecurityConfig() {
if (_securityConfig == null) {
log.trace 'Building security config since there is no cached config'
reloadSecurityConfig()
}
_securityConfig
}
/**
* For testing only.
* @param config the config
*/
static void setSecurityConfig(ConfigObject config) {
_securityConfig = config
}
/** Reset the config for testing or after a dev mode Config.groovy change. */
static synchronized void resetSecurityConfig() {
_securityConfig = null
log.trace 'reset security config'
}
/**
* Allow a secondary plugin to add config attributes.
* @param className the name of the config class.
*/
static synchronized void loadSecondaryConfig(String className) {
mergeConfig securityConfig, className
log.trace 'loaded secondary config {}', className
}
/** Force a reload of the security configuration. */
static void reloadSecurityConfig() {
mergeConfig ReflectionUtils.securityConfig, 'DefaultSecurityConfig'
log.trace 'reloaded security config'
}
/**
* Check if the request was triggered by an Ajax call.
* @param request the request
* @return true if Ajax
*/
static boolean isAjax(HttpServletRequest request) {
String ajaxHeaderName = (String)ReflectionUtils.getConfigProperty('ajaxHeader')
// check the current request's headers
if (XML_HTTP_REQUEST == request.getHeader(ajaxHeaderName)) {
return true
}
def ajaxCheckClosure = ReflectionUtils.getConfigProperty('ajaxCheckClosure')
if (ajaxCheckClosure instanceof Closure) {
def result = ajaxCheckClosure(request)
if (result instanceof Boolean && result) {
return true
}
}
// look for an ajax=true parameter
if ('true' == request.getParameter('ajax')) {
return true
}
// process multipart requests
MultipartHttpServletRequest multipart = (MultipartHttpServletRequest)request.getAttribute(MULTIPART_HTTP_SERVLET_REQUEST_KEY)
if ('true' == multipart?.getParameter('ajax')) {
return true
}
// check the SavedRequest's headers
HttpSession httpSession = request.getSession(false)
if (httpSession) {
SavedRequest savedRequest = (SavedRequest)httpSession.getAttribute(SAVED_REQUEST)
if (savedRequest) {
return savedRequest.getHeaderValues(ajaxHeaderName).contains(MULTIPART_HTTP_SERVLET_REQUEST_KEY)
}
}
false
}
/**
* Register a provider bean name.
*
* Note - only for use by plugins during bean building.
*
* @param beanName the Spring bean name of the provider
*/
static void registerProvider(String beanName) {
providerNames.add 0, beanName
log.trace 'Registered bean "{}" as a provider', beanName
}
/**
* Register a logout handler bean name.
*
* Note - only for use by plugins during bean building.
*
* @param beanName the Spring bean name of the handler
*/
static void registerLogoutHandler(String beanName) {
logoutHandlerNames.add 0, beanName
log.trace 'Registered bean "{}" as a logout handler', beanName
}
/**
* Register an AfterInvocationProvider bean name.
*
* Note - only for use by plugins during bean building.
*
* @param beanName the Spring bean name of the provider
*/
static void registerAfterInvocationProvider(String beanName) {
afterInvocationManagerProviderNames.add 0, beanName
log.trace 'Registered bean "{}" as an AfterInvocationProvider', beanName
}
/**
* Register a voter bean name.
*
* Note - only for use by plugins during bean building.
*
* @param beanName the Spring bean name of the voter
*/
static void registerVoter(String beanName) {
voterNames.add 0, beanName
log.trace 'Registered bean "{}" as a voter', beanName
}
/**
* Register a filter bean name in a specified position in the chain.
*
* Note - only for use by plugins during bean building - to register at runtime
* (preferably in BootStrap) use clientRegisterFilter.
*
* @param beanName the Spring bean name of the filter
* @param position the position
*/
static void registerFilter(String beanName, SecurityFilterPosition position) {
registerFilter beanName, position.order
}
/**
* Register a filter bean name in a specified position in the chain.
*
* Note - only for use by plugins during bean building - to register at runtime
* (preferably in BootStrap) use clientRegisterFilter.
*
* @param beanName the Spring bean name of the filter
* @param order the position (see {@link SecurityFilterPosition})
*/
static void registerFilter(String beanName, int order) {
String oldName = orderedFilters[order]
assert oldName == null, "Cannot register filter '$beanName' at position $order; '$oldName' is already registered in that position"
orderedFilters[order] = beanName
log.trace 'Registered bean "{}" as a filter at order {}', beanName, order
}
/**
* Register a filter in a specified position in the chain.
*
* Note - this is for use in application code after the plugin has initialized,
* e.g. in BootStrap where you want to register a custom filter in the correct
* order without dealing with the existing configured filters.
*
* @param beanName the Spring bean name of the filter
* @param position the position
*/
static void clientRegisterFilter(String beanName, SecurityFilterPosition position) {
clientRegisterFilter beanName, position.order
}
/**
* Register a filter in a specified position in the chain.
*
* Note - this is for use in application code after the plugin has initialized,
* e.g. in BootStrap where you want to register a custom filter in the correct
* order without dealing with the existing configured filters.
*
* @param beanName the Spring bean name of the filter
* @param order the position (see {@link SecurityFilterPosition})
*/
@SuppressWarnings('deprecation')
static void clientRegisterFilter(String beanName, int order) {
Filter oldFilter = configuredOrderedFilters.get(order)
assert !oldFilter,
"Cannot register filter '$beanName' at position $order; '$oldFilter' is already registered in that position"
Filter filter = getBean(beanName)
configuredOrderedFilters[order] = filter
List filterChains = getBean('securityFilterChains', List)
mergeFilterChains configuredOrderedFilters, filter, beanName, order, filterChains
log.trace 'Client registered bean "{}" as a filter at order {}', beanName, order
log.trace 'Updated filter chain: {}', filterChains
}
private static void mergeFilterChains(Map orderedFilters, Filter filter, String beanName,
int order, List filterChains) {
Map filterToPosition = new HashMap()
orderedFilters.each { Integer position, Filter f -> filterToPosition[f] = position }
List