【发布时间】:2021-03-10 06:32:11
【问题描述】:
我有一些 API,一些资源应该可供所有人使用,其余的则供用户使用。
为了保护资源,我实现了一个扩展 WebSecurityConfigurerAdapter 的类,如下所示:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(final HttpSecurity http) throws Exception
{
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.authenticationManagerResolver((request) -> http.getSharedObject(AuthenticationManager.class))
.and().oauth2Login()
.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and().cors();
}
}
然后我尝试关注https://www.baeldung.com/spring-deny-access 以让每个人都可以访问一些资源
所以我按照this example做了
GlobalMethodSecurityConfiguration & WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration
{
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return new CustomPermissionAllowedMethodSecurityMetadataSource();
}
@Configuration
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.authenticationManagerResolver((request) -> http.getSharedObject(AuthenticationManager.class))
.and().oauth2Login()
.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and().cors();
}
}
}
以及CustomPermissionAllowedMethodSecurityMetadataSource的实现
public class CustomPermissionAllowedMethodSecurityMetadataSource extends AbstractFallbackMethodSecurityMetadataSource
{
@Override
protected Collection<ConfigAttribute> findAttributes(Method method, Class<?> targetClass)
{
Annotation[] annotations = AnnotationUtils.getAnnotations(method);
List attributes = new ArrayList<>();
// if the class is annotated as @Controller we should by default deny access to all methods
if (AnnotationUtils.findAnnotation(targetClass, Controller.class) != null)
{
attributes.add(DENY_ALL_ATTRIBUTE);
}
if (annotations != null)
{
for (Annotation a : annotations)
{
// but not if the method has at least a PreAuthorize or PostAuthorize annotation
if (a instanceof PreAuthorize || a instanceof PostAuthorize)
{
return null;
}
}
}
return attributes;
}
@Override
protected Collection<ConfigAttribute> findAttributes(Class<?> clazz)
{
return null;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes()
{
return null;
}
}
最后,我在 rest 控制器中添加了端点:
@PreAuthorize("permitAll()")
很遗憾,没有用户,我无法访问此端点。
我是否使用了 GlobalMethodSecurityConfiguration 和 WebSecurityConfigurerAdapter 错误?
这是实现我在开头提到的正确方法(一些端点受保护,一些没有)?
【问题讨论】:
-
您确定没有
GlobalMethodSecurityConfiguration的第一个配置让未经身份验证的请求访问您的控制器吗?因为你的配置是:.anyRequest().authenticated()
标签: java spring spring-boot spring-security