Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth2 clientSecret shouldn't be required for implicit flow #1592

Closed
gonzalad opened this issue Dec 1, 2016 · 3 comments
Closed

OAuth2 clientSecret shouldn't be required for implicit flow #1592

gonzalad opened this issue Dec 1, 2016 · 3 comments
Assignees
Labels
Milestone

Comments

@gonzalad
Copy link
Contributor

gonzalad commented Dec 1, 2016

I'm using OAuth2 implicit flow and there's an issue when I set clientSecret to null :
the URL generated from swagger js for starting the OAuth2 authentication flow contains an undefined client_id (on serverside, clientId is not empty).

Sample URL :
http://localhost:9080/oidc/idp/authorize?response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3A7777%2Fwebjars%2Fspringfox-swagger-ui%2Fo2c.html&realm=undefined&client_id=undefined&scope=openid&state=oauth2

The issue appears to be in https://github.com/springfox/springfox/blob/2.6.1/springfox-swagger-ui/src/web/js/springfox.js#L71 : OAuth2 is initialized only if clientSecret is set.

What version of the library are you using? 2.6.0 (but the LOC in question is also in 2.6.1)

Thanks,
Adrian

Additional resources

Here's the JSON returned from /swagger-resources/configuration/security :

{  
   "clientId":"FFWtj97yGiRqdQ",
   "realm":"oauth2",
   "appName":"SCIM Service",
   "apiKeyVehicle":"header",
   "scopeSeparator":" "
}

Here's a fragment from my Spring Boot Config (the important thing being the SecurityConfiguration : clientSecret is set to null in the constructor):

@Configuration
public class SwaggerConfig {

    public static final String SECURITY_SCHEME_OAUTH2 = "oauth2";

    private static final String OAUTH2_SCOPE_SEPARATOR = " ";

    @Autowired
    private Environment environment;

    @Bean
    public Docket myApi(ServletContext servletContext, ResourceServerConfigurer resourceServerConfigurer,
            OAuth2AutoConfiguration oAuth2AutoConfiguration, List<SecurityScheme> securitySchemes,
            List<SecurityContext> securityContexts) {
        return new Docket(DocumentationType.SWAGGER_2)
                .host(host())
                .securitySchemes(securitySchemes != null ? securitySchemes : new ArrayList<SecurityScheme>())
                .securityContexts(securityContexts)
                .pathProvider(pathProvider(servletContext))
                .groupName("org.mycompany.iam.im.my")
                .apiInfo(myApiInfo())
                .select()
                .paths(regex("/(Groups|Users|Me|Schemas|ResourceTypes|ServiceProviderConfig).*"))
                .build();
    }

    @Bean
    public SecurityContext securityContext() {
        return SecurityContext.builder().securityReferences(defaultAuth()).build();
    }

    @Bean
    @ConditionalOnProperty("security.oauth2.client.clientId") // improve this condition
    public SecurityScheme securityScheme(Environment environment, OAuth2ClientProperties clientProperties) {
        LoginEndpoint loginEndpoint =
                new LoginEndpoint(environment.getRequiredProperty("security.oauth2.client.user-authorization-uri"));
        GrantType grantType = new ImplicitGrant(loginEndpoint, "access_token");
        return new OAuthBuilder().name(SECURITY_SCHEME_OAUTH2).grantTypes(Arrays.asList(grantType)).scopes(scopes()).build();
    }

    @Bean
    public SecurityConfiguration security() {
        return new SecurityConfiguration(// <19>
                environment.getRequiredProperty("swagger.oauth2.clientId"), null, SECURITY_SCHEME_OAUTH2,
                myApiInfo().getTitle(), null, ApiKeyVehicle.HEADER, null, OAUTH2_SCOPE_SEPARATOR);
    }

    private List<AuthorizationScope> scopes() {
        List<AuthorizationScope> authorizationScopes = new ArrayList<>();
        AuthorizationScope authorizationScope = new AuthorizationScope("account:list", "Account vi");
        authorizationScopes.add(authorizationScope);
        authorizationScopes.addAll(defaultScope());
        return authorizationScopes;
    }

    private List<SecurityReference> defaultAuth() {
        return Arrays.asList(new SecurityReference(SECURITY_SCHEME_OAUTH2, defaultScope().toArray(new AuthorizationScope[] {})));
    }

    private List<AuthorizationScope> defaultScope() {
        AuthorizationScope authorizationScope = new AuthorizationScope("openid", "Basic Open ID Connect Scope");
        List<AuthorizationScope> authorizationScopes = new ArrayList<>();
        authorizationScopes.add(authorizationScope);
        return authorizationScopes;
    }

    private ApiInfo myApiInfo() {
        return new ApiInfoBuilder()
                .title("my Service")
                .description("The service to manage users for all mycompany products.")
                .contact(new Contact("bla", null, null))
                .license("Apache License Version 2.0")
                .licenseUrl("https://github.com/mycompany/bla#license")
                .version("2.0")
                .build();
    }


    private String host() {
        return environment.getProperty("swagger.host", String.class);
    }

    private String basePath() {
        return environment.getProperty("swagger.basePath", String.class);
    }

    private PathProvider pathProvider(ServletContext servletContext) {
        return new RelativePathProvider(servletContext) {

            @Override
            protected String applicationPath() {
                if (host() == null || basePath() == null) {
                    return super.applicationPath();
                } else {
                    return basePath();
                }
            }

            @Override
            protected String getDocumentationPath() {
                if (host() == null || basePath() == null) {
                    return super.getDocumentationPath();
                } else {
                    return applicationPath();
                }
            }
        };
    }
}
@gonzalad
Copy link
Contributor Author

gonzalad commented Dec 1, 2016

Proposed PR is here : #1593

@ouyangyaxiong
Copy link

mark

@dilipkrish dilipkrish added this to the 2.7.0 milestone Dec 7, 2016
@dilipkrish
Copy link
Member

@gonzalad thanks for the proposal/PR. Will review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants