spring-cloud / spring-cloud-common-security-config

A common security infrastructure used by Spring Cloud Data Flow and the projects in its ecosystem
19 stars 32 forks source link

Misleading behavior when map-oauth-scopes=true and no roles were matched to the user's scopes #72

Open dbahatSAP opened 4 years ago

dbahatSAP commented 4 years ago

Hello,

I've been trying to configure the latest SCDF to authenticate with UAA. While authentication seems to work, when using custom authorization using map-oauth-scopes, I ended up getting an exception from CustomPlainOAuth2UserService.loadUser, which attempts to call spring security DefaultOAuth2UserService, stating that "authorities cannot be empty". To my understanding (and looking at https://docs.cloudfoundry.org/api/uaa/version/74.4.0/index.html#introspect-token), authorities are only applicable for client tokens.

@ghillert Any idea how should this flow work?

Here's additional info: 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT 2020-01-02 15:58:07.345 ERROR 7 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT java.lang.IllegalArgumentException: authorities cannot be empty 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT at org.springframework.util.Assert.notEmpty(Assert.java:464) 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT at org.springframework.security.oauth2.core.user.DefaultOAuth2User.(DefaultOAuth2User.java:63) 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT at org.springframework.cloud.common.security.support.CustomPlainOAuth2UserService.loadUser(CustomPlainOAuth2UserService.java:54) 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT at org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider.authenticate(OAuth2LoginAuthenticationProvider.java:116) 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175) 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:185) 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) 2020-01-02T15:58:07.34+0000 [APP/PROC/WEB/0] OUT at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)

dbahatSAP commented 4 years ago

Found the problem. In the case where map-oauth-scopes=true and a user scopes failed to match to any role, DefaultAuthoritiesMapper.mapScopesToAuthorities() returns an empty set, which is later passed to DefaultOAuth2User and fails on an assertion. Adding to the confusion is the SCDF UI, which upon authorization failure attempts to redirect to an error page only to get redirected back to the login page.

It would really help understand this case if we instead fail gracefully (and propagate the failure back to the UI, as was the behavior prior to the spring security upgrade).

sabbyanandan commented 4 years ago

Hi, @dbahatSAP. Thank you for the analysis! If you're familiar with the workflow to improve, please feel free to start a PR. One of us can pair with you to achieve the desired behavior.