我有自定义身份验证过滤器,该过滤器创建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安全性和带有Spring boot的自定义AuthenticationFilter所述
但是,当我尝试向控制器方法中添加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”时主体中认证对象的打印输出:
验证:org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken@817a0240:主体:org.springframework.security.ldap.userdetails.LdapUserDetailsImpl@c279eab8:Dn:uid = 1,ou = people,dc = cdpe,dc =米尔 用户名:xxxx@gmail.com;密码保护]; 启用:true;AccountNonExpired:true;CredentialsNonExpired:true;AccountNonLocked:true;授予的权限:ROLE_adminuser,ROLE_user;凭证:[受保护];已验证:true;详细信息:org.springframework.security.web.authentication.WebAuthenticationDetails@957e:RemoteIpAddress:127.0.0.1; SessionId:null;授予的权限:ROLE_adminuser,ROLE_user权限:[ROLE_adminuser,ROLE_user]
更新:我已经取得了一些进展。我将proxyTargetClass添加到以下注释中:
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
现在,当我调用我的方法时,我得到403 Forbidden返回。我不知道那是怎么回事。
Spring Security一直很繁琐的配置,唯一简单的方法是:
对于的配置X509AuthenticationFilter,HttpSecurityjavadoc给出了x509以下示例的方法(适用于您的配置- 有关原始示例,请参见javadoc):
X509AuthenticationFilter
HttpSecurity
x509
@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(); } }
带有以下指示:方法返回X509Configurer进一步的自定义。
X509Configurer
除非您有充分的理由做不同的事情(如果是这样,请说出来),我强烈建议您坚持使用该方法。
但是在控制器上使用post- post注解确实是一个坏主意,因为可以直接在HttpSecurity配置中完成。它迫使您使用proxyTargetClass = true。
proxyTargetClass = true
之前和之后的注释通常应用于不需要的服务层方法,proxyTargetClass=true因为服务通常通过允许JDK代理的接口连接到控制器。
proxyTargetClass=true