如何允许匿名访问端点

时间:2019-07-13 21:50:43

标签: spring-security microservices spring-cloud gateway

我有一个Spring Cloud体系结构,并且不允许匿名访问端点。

这是我的代码:

网关============================

Application:
    @SpringBootApplication
    @EnableZuulProxy
    @EnableEurekaClient
    @EnableResourceServer
    public class GatewayApplication {

        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class, args);
        }

        @Bean
        public FilterRegistrationBean<?> corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true);
            config.addAllowedOrigin("*");
            config.addAllowedHeader("*");
            config.addAllowedMethod("*");
            source.registerCorsConfiguration("/**", config);
            FilterRegistrationBean<?> bean = new FilterRegistrationBean<>(new CorsFilter(source));
            bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
            return bean;
        }
    }

Pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.geminiald</groupId>
    <artifactId>gateway</artifactId>
    <version>1.0.0</version>
    <name>gateway</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

bootstrap.properties:

spring.cloud.config.name=gateway
spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/

application.properties:

security.oauth2.resource.user-info-uri=http://localhost:8083/user

此外,我有一个身份验证服务==================== 申请:

@SpringBootApplication
@EnableEurekaClient
@EnableAuthorizationServer
@EnableResourceServer
@EntityScan(basePackages = { "com.geminiald.authservice.models" })
@EnableJpaRepositories(basePackages = { "com.geminiald.authservice.repositories" })
public class AuthServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(AuthServiceApplication.class, args);
    }
}

@Configuration
public class AuthorizationServerConfig
                extends AuthorizationServerConfigurerAdapter {

    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    public AuthorizationServerConfig(
                    @Lazy BCryptPasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Autowired
    private AuthSettings settings;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security)
        throws Exception {
        security.checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients)
        throws Exception {
        clients.inMemory().withClient(settings.getClient())
                        .authorizedGrantTypes(
                                        settings.getAuthorizedGrantTypes())
                        .authorities(settings.getAuthorities())
                        .scopes(settings.getScopes())
                        .resourceIds(settings.getResourceIds())
                        .accessTokenValiditySeconds(settings
                                        .getAccessTokenValiditySeconds())
                        .secret(passwordEncoder.encode(settings.getSecret()));
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
        throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }
}

@Configuration
public class AuthenticationMananagerProvider
                extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Autowired
    private BCryptPasswordEncoder encoder;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Autowired
    public void authenticationManager(AuthenticationManagerBuilder builder,
        UserRepository repository) throws Exception {

        builder.userDetailsService(userDetailsService).passwordEncoder(encoder);
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        BCryptPasswordEncoder bCryptPasswordEncoder =
                        new BCryptPasswordEncoder();
        return bCryptPasswordEncoder;
    }

    @Bean
    public FilterRegistrationBean<?> corsFilter() {
        UrlBasedCorsConfigurationSource source =
                        new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<?> bean =
                        new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }

}

application.properties:

# H2 Database configuration
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=sa
spring.datasource.password=

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.initialization-mode=always

bootstrap.properties:

spring.cloud.config.name=auth-service
spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/

我有一个Dc-tool-box-service: 应用==========

@SpringBootApplication
@EnableEurekaClient
@EnableResourceServer
@EntityScan(basePackages = { "com.geminiald.dctoolbox.models" })
@EnableJpaRepositories(basePackages = { "com.geminiald.dctoolbox.repositories" })
public class DcToolBoxServiceApplication {

    public static void main(String[] args) throws IOException {
        SpringApplication.run(DcToolBoxServiceApplication.class, args);
    }
}

bootstrap.properties:

spring.cloud.config.name=dc-tool-box-service
spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/

application.properties:

# H2 Database configuration
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=sa
spring.datasource.password=

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.initialization-mode=always

spring.servlet.multipart.max-file-size=-1
spring.servlet.multipart.max-request-size=-1

security.oauth2.resource.user-info-uri=http://localhost:8083/user

在那里,您可以从配置服务中看到所有* .properties文件: 身份验证服务:

spring.application.name=auth-service
server.port=8083

eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5
eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/

网关:

spring.application.name=gateway
server.port=8000

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
zuul.host.connect-timeout-millis= 15000
zuul.host.socket-timeout-millis= 60000
ribbon.ReadTimeout= 60000
ribbon.ConnectTimeout= 60000

eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5

zuul.routes.discovery.path=/discovery/**
zuul.routes.discovery.sensitive-headers=Set-Cookie,Authorization
zuul.routes.discovery.url=http://localhost:8082
hystrix.command.discovery.execution.isolation.thread.timeoutInMilliseconds=600000

zuul.routes.auth-service.path=/auth-service/**
zuul.routes.auth-service.sensitive-headers=Set-Cookie
hystrix.command.auth-service.execution.isolation.thread.timeoutInMilliseconds=600000

zuul.routes.dc-tool-box-service.path=/dc-tool-box-service/**
zuul.routes.dc-tool-box-service.sensitive-headers=Set-Cookie
hystrix.command.dc-tool-box-service.execution.isolation.thread.timeoutInMilliseconds=600000

dc-tool-box-service:

spring.application.name=dc-tool-box-service
server.port=8086

eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5
eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/

为此,我在dc-tool-box-service中有两个端点:/ persons / signup和/ dossiers。 我想保持/ dossiers的安全性,但是/ persons / signup应该是匿名的。这样任何人都可以无需身份验证即可访问。

这就是我在网关中的情况

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers("/dc-tool-box-service/persons/signup").anonymous();
    }
}

在邮递员中,我可以使用令牌访问/ dossiers,但会收到消息:

{
    "error": "unauthorized",
    "error_description": "Full authentication is required to access this resource"
}

当我尝试在标题中未提供属性授权的情况下访问/ persons / signup时。

有人可以帮我吗?我会很感激。

1 个答案:

答案 0 :(得分:1)

您需要使用permitAll()而不是anonymous()

替换:.antMatchers("/dc-tool-box-service/persons/signup").anonymous();

使用:.antMatchers("/dc-tool-box-service/persons/signup").permitAll();

这将授权所有匿名和登录用户。

anonymous()的问题在于,只有拥有ROLE_ANONYMOUS的用户才能访问该端点。

编辑::安全性顺序仍然不起作用,因为您的第一个安全性约束是对您应用程序的任何请求均应进行身份验证,然后您已配置为允许/signup请求。更改这些权限的顺序。

http.authorizeRequests()
    .antMatchers("/dc-tool-box-service/persons/signup").permitAll()
    .and()
    .authorizeRequests()
    .anyRequest().authenticated();