Spring-security/Grails 应用程序 - 未调用自定义 WebSecurity 配置
Posted
技术标签:
【中文标题】Spring-security/Grails 应用程序 - 未调用自定义 WebSecurity 配置【英文标题】:Spring-security/Grails app - Custom WebSecurity configurations not getting called 【发布时间】:2019-07-02 21:51:13 【问题描述】:我的项目基于 Grail 2.5.6 和 Spring 插件。我正在尝试创建一个自定义身份验证提供程序、过滤器和令牌,以扩展它们各自的基本类。
this.getAuthenticationManager().authenticate(authRequest)
在我的过滤器中,身份验证管理器始终为空。因此,它抛出无法在空对象上调用 authenticate()。当我在 authenticationManager 上进行调试时,它列出了其他提供程序名称,但我的自定义名称除外。
这是我的自定义网络安全配置
@Configuration
@EnableGlobalMethodSecurity(securedEnabled=true)
public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter
OrbisAuthenticationProvider orbisAuthenticationProvider
public CustomWebSecurityConfig()
super()
log.debug "configure custom security"
print("configure custom security")
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
print("configure method 1")
log.debug "configure method 1"
auth.authenticationProvider(orbisAuthenticationProvider)
@Bean(name= BeanIds.AUTHENTICATION_MANAGER)
@Override
AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean()
@Bean
OrbisAuthenticationFilter orbisAuthenticationProvider() throws Exception
log.debug "orbis Authentication provider"
OrbisAuthenticationProvider orbisAuthenticationProvider = new OrbisAuthenticationProvider(authenticationManagerBean())
return orbisAuthenticationProvider
@Bean
@Autowired
public OrbisAuthenticationFilter orbisAuthenticationFilter() throws Exception
print("configure orbis filtr")
OrbisAuthenticationFilter oaf = new OrbisAuthenticationFilter()
oaf.setAuthenticationManager(authenticationManagerBean())
oaf.setFilterProcessesUrl("j_orbis_security_check")
oaf.setUsernameParameter("email")
oaf.setPasswordParameter("password")
oaf.setAuthenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler()
.setDefaultTargetUrl("/oauth/authorize"))
oaf.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler()
.setDefaultFailureUrl("/loginWithOrbis"))
oaf.afterPropertiesSet()
return oaf
在调试时,看起来这些方法中的任何一个都没有被调用。注释似乎不足以被拾取。我也试过@ComponentScan。
我必须在某处注入此安全配置吗?如何让 authManager 在我的过滤器中可用?
OrbisAuthFilter
class OrbisAuthenticationFilter extends AbstractAuthenticationProcessingFilter
// @Autowired
OrbisAuthenticationProvider orbisAuthenticationProvider
OrbisAuthenticationFilter()
super("/j_orbis_security_check")
orbisAuthenticationProvider = new OrbisAuthenticationProvider()
void afterPropertiesSet()
assert authenticationManager != null, 'authenticationManager must be specified'
@Override
Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException
String username = request.getParameter("email")
String password = request.getParameter("password")
String accessCode = request.getParameter("accessCode")
OrbisAuthenticationToken authRequestForAuthentication = new OrbisAuthenticationToken(username, password, accessCode)
// This throws error because getAuthenticationManager returns null
// authRequestForAuthentication = this.getAuthenticationManager.authenticate(authRequestForAuthentication)
//This works if I instantiate the orbis provider object in the constructor
authRequestForAuthentication = this.orbisAuthenticationProvider.authenticate(authRequestForAuthentication)
SecurityContextHolder.getContext().setAuthentication(authRequestForAuthentication)
return authRequestForAuthentication
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest)
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
@Override
@Autowired
public void setAuthenticationManager(AuthenticationManager authenticationManager)
super.setAuthenticationManager(authenticationManager);
OrbisAuthProvider
class OrbisAuthenticationProvider implements AuthenticationProvider
@Override
Authentication authenticate(Authentication authentication) throws AuthenticationException
OrbisAuthenticationToken orbisAuth = (OrbisAuthenticationToken) authentication
String username = orbisAuth.principal
String password = orbisAuth.credentials
String orbisAccessCode = orbisAuth.orbisAccessCode
def urlToUse = 'https://coopstatus.neu.edu/sail_api/full.aspx?' + 'ac=' + orbisAccessCode + '&e='+ username + '&p=' + password
HttpClient httpClient = DefaultHttpClient.newInstance()
HttpGet getRequest = new HttpGet(urlToUse)
HttpResponse httpResponse = httpClient.execute(getRequest)
JSONObject orbisResponse = new JSONObject(httpResponse.getEntity().getContent().getText())
// if(orbisResponse.get("IsFound"))
// //Return error not authenticated
//
Collection<GrantedAuthority> orbisUserGrantedAuthorities = getLDAPUserAuthorities(orbisResponse.get("Email"))
orbisAuth = new OrbisAuthenticationToken(username, password, orbisAccessCode, orbisUserGrantedAuthorities)
return orbisAuth
private Collection<GrantedAuthority> getLDAPUserAuthorities(String username)
LDAPUserDetails currentLdapUserDetails
try
currentLdapUserDetails = new LDAPUserDetailsService().loadUserByOrbisUsername(username)
log.debug currentLdapUserDetails
catch(org.springframework.security.core.userdetails.UsernameNotFoundException e)
log.error("User " + username + " not found in ldap", e)
Collection<GrantedAuthority> authorities = new ArrayList<>()
for (String authority : currentLdapUserDetails.authorities)
authorities.add(new SimpleGrantedAuthority(authority))
return authorities
@Override
public boolean supports(Class<?> authentication)
return (OrbisAuthenticationToken.class
.isAssignableFrom(authentication));
Resources.groovy
import edu.neu.security.OrbisAuthenticationFilter
import edu.neu.security.OrbisAuthenticationProvider
beans =
userDetailsService(edu.neu.security.LDAPUserDetailsService)
orbisAuthenticationProvider(OrbisAuthenticationProvider)
orbisAuthenticationFilter(OrbisAuthenticationFilter)
orbisAuthenticationProvider = ref("orbisAuthenticationProvider")
requiresAuthenticationRequestMatcher = ref('filterProcessUrlRequestMatcher')
// This throws error during startup. Unable to init bean
// authenicationManager = ref("authenicationManager")
myOAuth2ProviderFilter(OAuth2ProviderFilters)
//grailsApplication = ref('grailsApplication')
// properties
我遵循了这个项目的一些概念:https://github.com/ppazos/cabolabs-ehrserver/
即使执行了整个过程并且 securityContext 设置为已验证,当我点击 oauth/authorize 以获取 Authorization_Code 时,它也会重定向回“/login/auth”。它仍然不知道用户已经过身份验证。
【问题讨论】:
【参考方案1】:当您向 AuthenticationManagerBuilder bean(来自 AuthenticationConfiguration
)添加身份验证提供程序时,不会使用您声明的身份验证管理器 bean。
试试:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled=true)
public class CustomWebSecurityConfig
OrbisAuthenticationProvider lwoAuthProvider;
public CustomWebSecurityConfig()
//
@Bean(name= BeanIds.AUTHENTICATION_MANAGER)
AuthenticationManager authenticationManagerBean() throws Exception
return new ProviderManager(Arrays.asList(lwoAuthProvider));
您的 AuthenticationManager bean 应该被拾取并将用于方法安全性。如果它由 Spring 管理,您也可以在过滤器中 @Autowire
它,或者在实例化过滤器的 @Configuration
类中 @Autowire
它。
注意:上述类不会创建任何 Spring Security 过滤器。
(无论如何都没有创建过滤器链 - 你没有用 @EnableWebSecurity
注释你的类)
【讨论】:
嗨!感谢您的回复。我添加了@EnableWebSecurity,但没有注入整个自定义安全配置文件。我的调试语句都没有发布。以上是关于Spring-security/Grails 应用程序 - 未调用自定义 WebSecurity 配置的主要内容,如果未能解决你的问题,请参考以下文章