PreAuthorize 和自定义 AuthenticationFilter with Spring boot
PreAuthorize and custom AuthenticationFilter with Spring boot
我有自定义身份验证过滤器,它创建 PreAuthenticatedAuthenticationToken 并将其存储在安全上下文中。过滤器工作正常,它使用适当的授权权限创建令牌 "ROLE_user" 和 "ROLE_adminuser"。这是我的配置:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
X509AuthenticationFilter filter = new X509AuthenticationFilter()
filter.setAuthenticationManager(authenticationManager())
http.addFilterAfter(filter, SecurityContextPersistenceFilter.class)
http.authorizeRequests().anyRequest().permitAll()
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean()
X509AuthenticationFilter filter = new X509AuthenticationFilter()
filter.setAuthenticationManager(authenticationManager())
registrationBean.setFilter(filter)
registrationBean.setEnabled(false)
return registrationBean
}
我在 SecurityContextPersistenceFilter 之前插入过滤器,如 Spring security and custom AuthenticationFilter with Spring boot 中所述。
这似乎工作正常,但是,当我尝试向我的控制器方法添加 PreAuthorize 注释时,如下所示:
@Controller
@RequestMapping("/security")
class SecurityController {
@RequestMapping("/authenticate")
@PreAuthorize("hasRole('ROLE_user')")
@ResponseBody
ResponseEntity<String> authenticate(HttpServletRequest request, Principal principal) {
println "authenticate: " + SecurityContextHolder.getContext().getAuthentication()
return new ResponseEntity<String>(getPreAuthenticatedPrincipal(request), HttpStatus.OK)
}
我收到 404 错误。如果我注释掉 PreAuthorize 注释,则方法调用有效,您可以看到我打印出身份验证信息,并且经过身份验证的用户具有 ROLE_user 和 ROLE_adminuser 的授权权限。我不确定我做错了什么。
这是注释掉 "PreAuthorize" 时主体中身份验证对象的打印输出:
authenticate:
org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken@817a0240:
Principal:
org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@c279eab8:
Dn: uid=1,ou=people,dc=cdpe,dc=mil; Username: xxxx@gmail.com;
Password: [PROTECTED]; Enabled: true; AccountNonExpired: true;
CredentialsNonExpired: true; AccountNonLocked: true; Granted
Authorities: ROLE_adminuser, ROLE_user; Credentials: [PROTECTED];
Authenticated: true; Details:
org.springframework.security.web.authentication.WebAuthenticationDetails@957e:
RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities:
ROLE_adminuser, ROLE_user authorities: [ROLE_adminuser, ROLE_user]
更新:我取得了一些进步。我将 proxyTargetClass 添加到以下注释中:
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
现在我在调用我的方法时收到 403 Forbidden returns。我不知道那在做什么。
Spring 安全配置一直很繁琐,万无一失的方法只有:
- 要么是这方面的专家,要么准备好查看源代码,然后你就可以手工完成困难的事情
- 或尽可能多地使用框架提供的内容,并尽可能使用文档中的示例
对于 X509AuthenticationFilter
的配置,HttpSecurity
javadoc 给出了以下示例的方法 x509
(适应您的配置 - 原始配置请参阅 javadoc):
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().permitAll()
// Example x509() configuration
.x509();
}
}
具有以下指示:方法 returns X509Configurer
用于进一步自定义。
除非您有充分的理由采取不同的做法(如果是这种情况请说明)我强烈建议您坚持使用该方法。
但是在控制器上使用预 post 注释确实是一个坏主意,因为可以直接在 HttpSecurity
配置中完成。它强迫你使用 proxyTargetClass = true
.
Pre 和 post 注释通常应用于不需要 proxyTargetClass=true
的服务层方法,因为服务通常通过允许 JDK 代理的接口连接到控制器。
感谢您的帮助。对于这个例子,我被迫重新使用已经工作的 Spring 安全自定义过滤器。我只是想让它在 spring-boot 上下文中工作。
在上面的代码中添加 proxyTargetClass = true
似乎解决了这个问题。
我有自定义身份验证过滤器,它创建 PreAuthenticatedAuthenticationToken 并将其存储在安全上下文中。过滤器工作正常,它使用适当的授权权限创建令牌 "ROLE_user" 和 "ROLE_adminuser"。这是我的配置:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
X509AuthenticationFilter filter = new X509AuthenticationFilter()
filter.setAuthenticationManager(authenticationManager())
http.addFilterAfter(filter, SecurityContextPersistenceFilter.class)
http.authorizeRequests().anyRequest().permitAll()
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean()
X509AuthenticationFilter filter = new X509AuthenticationFilter()
filter.setAuthenticationManager(authenticationManager())
registrationBean.setFilter(filter)
registrationBean.setEnabled(false)
return registrationBean
}
我在 SecurityContextPersistenceFilter 之前插入过滤器,如 Spring security and custom AuthenticationFilter with Spring boot 中所述。
这似乎工作正常,但是,当我尝试向我的控制器方法添加 PreAuthorize 注释时,如下所示:
@Controller
@RequestMapping("/security")
class SecurityController {
@RequestMapping("/authenticate")
@PreAuthorize("hasRole('ROLE_user')")
@ResponseBody
ResponseEntity<String> authenticate(HttpServletRequest request, Principal principal) {
println "authenticate: " + SecurityContextHolder.getContext().getAuthentication()
return new ResponseEntity<String>(getPreAuthenticatedPrincipal(request), HttpStatus.OK)
}
我收到 404 错误。如果我注释掉 PreAuthorize 注释,则方法调用有效,您可以看到我打印出身份验证信息,并且经过身份验证的用户具有 ROLE_user 和 ROLE_adminuser 的授权权限。我不确定我做错了什么。
这是注释掉 "PreAuthorize" 时主体中身份验证对象的打印输出:
authenticate: org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken@817a0240: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@c279eab8: Dn: uid=1,ou=people,dc=cdpe,dc=mil; Username: xxxx@gmail.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_adminuser, ROLE_user; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_adminuser, ROLE_user authorities: [ROLE_adminuser, ROLE_user]
更新:我取得了一些进步。我将 proxyTargetClass 添加到以下注释中:
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
现在我在调用我的方法时收到 403 Forbidden returns。我不知道那在做什么。
Spring 安全配置一直很繁琐,万无一失的方法只有:
- 要么是这方面的专家,要么准备好查看源代码,然后你就可以手工完成困难的事情
- 或尽可能多地使用框架提供的内容,并尽可能使用文档中的示例
对于 X509AuthenticationFilter
的配置,HttpSecurity
javadoc 给出了以下示例的方法 x509
(适应您的配置 - 原始配置请参阅 javadoc):
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().permitAll()
// Example x509() configuration
.x509();
}
}
具有以下指示:方法 returns X509Configurer
用于进一步自定义。
除非您有充分的理由采取不同的做法(如果是这种情况请说明)我强烈建议您坚持使用该方法。
但是在控制器上使用预 post 注释确实是一个坏主意,因为可以直接在 HttpSecurity
配置中完成。它强迫你使用 proxyTargetClass = true
.
Pre 和 post 注释通常应用于不需要 proxyTargetClass=true
的服务层方法,因为服务通常通过允许 JDK 代理的接口连接到控制器。
感谢您的帮助。对于这个例子,我被迫重新使用已经工作的 Spring 安全自定义过滤器。我只是想让它在 spring-boot 上下文中工作。
在上面的代码中添加 proxyTargetClass = true
似乎解决了这个问题。