多个oauth2服务和配置

时间:2017-04-06 12:04:35

标签: spring spring-boot oauth-2.0

我有一个使用配置A扩展的现有Spring应用程序 ResourceServerConfigureAdapter 以保护API免受内部oauth服务A. 我正在尝试添加另一个扩展 WebSecurityConfigurerAdapter 的配置B,它针对外部oauth提供程序进行身份验证。

目标是继续B确定/ api /相关端点的身份验证,而A确定Web应用程序的整体登录。

以下是使用ResourceServerConfigureAdapter的现有代码: -

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

@Value("${oauth.clientId}")
private String clientId;

@Value("${oauth.clientSecret}")
private String clientSecret;

@Autowired
private RestTemplate restTemplate;

@Bean
public RemoteTokenServices remoteTokenServices() {
    RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
    remoteTokenServices.setRestTemplate(restTemplate);
    remoteTokenServices.setClientId(clientId);
    remoteTokenServices.setClientSecret(clientSecret);
    remoteTokenServices.setCheckTokenEndpointUrl("srvc://myservice/api/v2/oauth/check_token");
    return remoteTokenServices;
}

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.resourceId(null);
    resources.tokenServices(remoteTokenServices());
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http.anonymous()
        .and().authorizeRequests()
        .antMatchers("/api/secured/**").authenticated()
        .antMatchers("/api/**").permitAll();
}}

以下是使用WebSecurityConfigurerAdapter的代码: -

@SpringBootApplication
@EnableOAuth2Client
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class DemoService extends WebSecurityConfigurerAdapter {

    @Autowired
    OAuth2ClientContext oauth2ClientContext;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**", "/webjars/**").permitAll().anyRequest()
                .authenticated().and().exceptionHandling()
                .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")).and().logout()
                .logoutSuccessUrl("/").permitAll().and().csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
                .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
        // @formatter:on
    }

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

    @Bean
    public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(filter);
        registration.setOrder(-100);
        return registration;
    }

    private Filter ssoFilter() {
        OAuth2ClientAuthenticationProcessingFilter googleFilter = new OAuth2ClientAuthenticationProcessingFilter(
                "/login/google");
        OAuth2RestTemplate googleTemplate = new OAuth2RestTemplate(google(), oauth2ClientContext);
        googleFilter.setRestTemplate(googleTemplate);
        UserInfoTokenServices tokenServices = new UserInfoTokenServices(googleResource().getUserInfoUri(),
                google().getClientId());
        tokenServices.setRestTemplate(googleTemplate);
        googleFilter.setTokenServices(
                new UserInfoTokenServices(googleResource().getUserInfoUri(), google().getClientId()));
        return googleFilter;
    }

    @Bean
    @ConfigurationProperties("google.client")
    public AuthorizationCodeResourceDetails google() {
        return new AuthorizationCodeResourceDetails();
    }

    @Bean
    @ConfigurationProperties("google.resource")
    public ResourceServerProperties googleResource() {
        return new ResourceServerProperties();
    }

}

他们两人单独运行良好,但在同一个项目中放在一起,问题开始显现。一切都编译并运行良好,但当我点击localhost:8080 /以下发生 - 页面加载正常但是当我点击localhost:8080 / login / google时,它会显示一个whitelabel错误页面,如下所示

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Apr 06 13:22:27 IST 2017
There was an unexpected error (type=Not Found, status=404).
Not Found

我尝试阅读一下有关ResourceServerConfigureAdapter和WebSecurityConfigurerAdapter的内容,我只能理解有某种过滤器顺序可以确定每个配置器的优先级。但这并没有帮助我解决这个问题。有什么指针吗?

更新: Swagger集成的另一个适配器也是项目的一部分。

@EnableSwagger2
@Configuration
public class SwaggerConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addRedirectViewController("/docs", "/swagger-ui.html");
        registry.addRedirectViewController("/docs/", "/swagger-ui.html");
        registry.addRedirectViewController("/docs.json", "/v2/api-docs");
    }

    @Bean
    public Docket swaggerSpringMvcPlugin() {
        return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(new ApiInfoBuilder()
                .title("Spring Boot Service")
                .description("Sample project documentation")
                .contact("a@b.com")
                .version("1.0")
                .license("Apache")
                .build())
            .forCodeGeneration(true)
            .ignoredParameterTypes(Principal.class)
            .useDefaultResponseMessages(false)
            .select()
            .paths(documentedPaths())
            .build();
    }

    private Predicate<String> documentedPaths() {
        return or(
            regex("/api.*"));
    }
}

1 个答案:

答案 0 :(得分:0)

.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);

OAuth2ClientAuthenticationProcessingFilter必须在OAuth2ClientContextFilter之后,OAuth2ClientAuthenticationProcessingFilter在请求错误时抛出redirect exception(否code等等),< / p>

OAuth2ClientContextFilter会抓住它并重定向到userAuthorizationUri;

BasicAuthenticationFilterOAuth2ClientContextFilter正常之前,所以您应该更改顺序:

@Autowired
private OAuth2ClientContextFilter oAuth2ClientContextFilter;

protected void configure(HttpSecurity http) throws Exception { 
    http
        .addFilterAfter(oAuth2ClientContextFilter, ExceptionTranslationFilter.class)
        .addFilterAfter(ssoFilter(), OAuth2ClientContextFilter.class);

}

更新:

还有另一个地方需要更新,如果你有多链,你应该定义请求匹配,默认值是'/ **',默认顺序ResourceServerConfiguration是3,默认WebSecurityConfigurerAdapter的顺序为100,ResourceServerConfiguration具有高优先级。

// only handle the request start with `/api`
http.requestMatcher(new AntPathRequestMatcher("/api/**"))
http.anonymous()
        .and().authorizeRequests()
        .antMatchers("/api/secured/**").authenticated()
        .antMatchers("/api/**").permitAll();

如果您通过更改订单将WebSecurityConfigurerAdapter置于ResourceServerConfiguration之前,则还应将WebSecurityConfigurerAdapter配置为不处理/api/**

// skip the request start with '/api'
http.requestMatcher(new RegexRequestMatcher("^(?!/api).*$", null))
    .authorizeRequests().antMatchers("/", "/login/**", "/webjars/**").permitAll().anyRequest()

UPDATE2:

.authorizeRequests().antMatchers("/", "/login**")

此匹配器与/login/google不符,请更新为/login/**,因此应该

.authorizeRequests().antMatchers("/", "/login/**").permitAll()