spring security 匿名访问安全吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring security 匿名访问安全吗相关的知识,希望对你有一定的参考价值。

参考技术A 试试下面这句

Java代码
<intercept-url pattern="/*" access="isAuthenticated()" />

意思是只有拥有权限的人才能访问
如果不行把*号去掉试试
注意<http>里 要添加一个
Java代码 收藏代码
use-expressions="true"
的属性
表示开启表达式.

另外再附一段表达式吧

引用

常用内建表达式
表达式 说明
hasRole([role]) 返回 true 如果当前主体拥有特定角色。
hasAnyRole([role1,role2]) 返回 true 如果当前主体拥有任何一个提供的角色 (使用逗号分隔的字符串队列)
principal 允许直接访问主体对象,表示当前用户
authentication 允许直接访问当前 Authentication对象 从SecurityContext中获得
permitAll 一直返回true
denyAll 一直返回false
isAnonymous() 如果用户是一个匿名登录的用户 就会返回 true
isRememberMe() 如果用户是通过remember-me 登录的用户 就会返回 true
isAuthenticated() 如果用户不是匿名用户就会返回true
isFullyAuthenticated() 如果用户不是通过匿名也不是通过remember-me登录的用户时, 就会返回true。
参考技术B spring security也就是被大家广为熟悉的acegi security,2007年底Acegi Security正式成为Spring Portfolio项目,并更名为Spring Security。Spring Security是一个能够为基于spring的企业应用系统提供描述性安全访问控制解决方案的安全框架。 他提供了一组可以基于springIoC(依赖注入,也称控制反转)和AOP(面向切面编程)应用上下文中配置的Bean,充分利用了Spring功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。本回答被提问者采纳

Spring Boot Security PreAuthenticated 场景,匿名访问

【中文标题】Spring Boot Security PreAuthenticated 场景,匿名访问【英文标题】:Spring Boot Security PreAuthenticated Scenario with Anonymous access 【发布时间】:2018-08-08 18:06:03 【问题描述】:

我有一个使用 Spring Security 的“pre-authenticated”身份验证方案 (SiteMinder) 的 Spring Boot (1.5.6) 应用程序。

我需要匿名公开执行器“健康”端点,这意味着对该端点的请求将通过 SiteMinder,因此 SM_USER 标头不会出现在 HTTP 请求中标题。

我面临的问题是,无论我如何尝试配置“健康”端点,框架都会抛出 org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException,因为当请求不通过时,预期的标头(“SM_USER”)不存在通过 SiteMinder。

这是我最初的安全配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .authorizeRequests().antMatchers("/cars/**", "/dealers/**")
                .hasAnyRole("CLIENT", "ADMIN")
            .and()
                .authorizeRequests().antMatchers("/health")
                .permitAll()
            .and()
                .authorizeRequests().anyRequest().denyAll()
            .and()
                .addFilter(requestHeaderAuthenticationFilter())
                .csrf().disable();
    

    @Bean
    public Filter requestHeaderAuthenticationFilter() throws Exception 
        RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter();
        filter.setAuthenticationManager(authenticationManager());
        return filter;
    

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.authenticationProvider(preAuthProvider());
    

    @Bean
    public AuthenticationProvider preAuthProvider() 
        PreAuthenticatedAuthenticationProvider authManager = new PreAuthenticatedAuthenticationProvider();
        authManager.setPreAuthenticatedUserDetailsService(preAuthUserDetailsService());
        return authManager;
    

    @Bean
    public AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> preAuthUserDetailsService() 
        return new UserDetailsByNameServiceWrapper<>(inMemoryUserDetails());
    

    @Bean
    public UserDetailsService inMemoryUserDetails() 
        return new InMemoryUserDetailsManager(getUserSource().getUsers());
    

    @Bean
    public UserHolder getUserHolder() 
        return new UserHolderSpringSecurityImple();
    

    @Bean
    @ConfigurationProperties
    public UserSource getUserSource() 
        return new UserSource();
    

我尝试了几种不同的方法来排除 /health 端点,但无济于事。

我尝试过的事情:

为匿名访问而不是 permitAll 配置健康端点:

http
   .authorizeRequests().antMatchers("/health")
   .anonymous()

将 WebSecurity 配置为忽略健康端点:

@Override
public void configure(WebSecurity web) throws Exception 
    web.ignoring().antMatchers("/health");

关闭所有执行器端点的安全性(不知道,但我正在抓住稻草):

management.security.enabled=false

查看日志,问题似乎是 RequestHeaderAuthenticationFilter 被注册为 top level 过滤器,而不是现有 securityFilterChain 中的过滤器:

.s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webRequestLoggingFilter' to: [/*]
o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestHeaderAuthenticationFilter' to: [/*]

根据我的理解,因为RequestHeaderAuthenticationFilter 扩展了AbstractPreAuthenticatedProcessingFilter,所以框架知道在链中插入过滤器的位置,这就是为什么我不修改 addFilterBefore 或 addFilter 之后变体。也许我应该是?有人知道明确插入过滤器的正确位置吗? (我认为在 Spring Security 的早期版本中删除了显式指定过滤器顺序的需要)

我知道我可以配置RequestHeaderAuthenticationFilter,这样如果标头不存在,它就不会引发异常,但我想尽可能保持这种状态。

我发现这个 SO 帖子似乎与我的问题相似,但不幸的是那里也没有答案。 spring-boot-security-preauthentication-with-permitted-resources-still-authenti

任何帮助将不胜感激! 谢谢!

【问题讨论】:

Filter invoke twice when register as Spring bean的可能重复 【参考方案1】:

问题确实是 RequestHeaderAuthenticationFilter 被注册为 both 作为***过滤器(不需要)以及在 Spring Security FilterChain 中(需要)。

“双重注册”的原因是因为 Spring Boot 会自动向 Servlet Container 注册任何 Filter Bean。

为了防止“自动注册”,我只需要像这样定义一个FilterRegistrationBean

@Bean
public FilterRegistrationBean registration(RequestHeaderAuthenticationFilter filter) 
    FilterRegistrationBean registration = new FilterRegistrationBean(filter);
    registration.setEnabled(false);
    return registration;

文档: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-disable-registration-of-a-servlet-or-filter

另一种/更简单的解决方案: 只是不要将RequestHeaderAuthenticationFilter 类标记为@Bean,这很好,因为该特定过滤器不需要任何类型的DI。通过不使用@Bean 标记过滤器,Boot 不会尝试自动注册它,从而无需定义 FilterRegistrationBean。

【讨论】:

【参考方案2】:

所提供的答案很可能并不完整,因为 Sean Casey 进行了如此多的试验和错误更改,以至于忘记了实际解决问题的配置。我发布了我认为具有正确配置的发现:

如果您错误地将RequestHeaderAuthenticationFilter 注册为@Bean,如原始答案所述,则将其删除。只需将其创建为普通实例并将其添加为过滤器即可正确注册它:

@Override
protected void configure(HttpSecurity http) throws Exception 
    RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter();
    // configure your filter
    http
        .authorizeRequests().anyRequest().authenticated()
        .and()
        .addFilter(filter)
        .csrf().disable();

Sean Casey 尝试但最初失败的神奇配置(由于 auth 过滤器的双重注册)是 WebSecurity 配置:

@Override
public void configure(WebSecurity web) throws Exception 
    web.ignoring().antMatchers("/health");

请注意,在这种情况下添加 HttpSecurity antMatchers 没有任何作用,似乎 WebSecurity 是优先处理并控制所发生的事情。

额外:根据 Spring Security 文档,WebSecurity.ignore 方法应该用于静态资源,而不是用于应该映射以允许所有用户的动态资源。但是在这种情况下,映射似乎被 PreAuthentication 过滤器覆盖,这会强制使用更激进的ignore 方案。

【讨论】:

以上是关于spring security 匿名访问安全吗的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security OAuth2 JWT 匿名令牌

Spring security - 允许匿名访问

Spring Security仅允许匿名访问

Spring Boot Security PreAuthenticated 场景,匿名访问

Spring security如何允许匿名访问大多数限制某些操作的站点

如何保护 Spring Security 中受 IP 地址限制的匿名访问?