spring-cloud / spring-cloud-dataflow-ui

This repo provides the Dashboard application of Spring Cloud Data Flow
https://dataflow.spring.io/
Apache License 2.0
212 stars 118 forks source link

Option to set Angular OAuth2 login page (backwards compatible with Spring-Security default OAuth2 login) #1887

Open klopfdreh opened 2 years ago

klopfdreh commented 2 years ago

As mentioned here https://github.com/spring-cloud/spring-cloud-dataflow-ui/issues/1867 - bootstrap shouldn't be used and removed.

When I tested Spring Cloud Data Flow Server 2.10.0-M2 and used a custom DataflowOAuthSecurityConfiguration for CSP settings, I found the login page to still use bootstrap.

image

claudiahub commented 2 years ago

@klopfdreh Thanks Tobias for finding this, I did some investigation on the Angular repo. It seems we're not injecting directly from Dataflow UI those two css files, Do you perhaps have a target URL for the page located in the above screenshot ? so I can then explore more outside the Angular context

Thanks

klopfdreh commented 2 years ago

It is just /login with OAuth2 configured. I am also going to search for it. 👍

claudiahub commented 2 years ago

@klopfdreh It seems there's no route associated in the Angular code. I guess the /login should be the redirected URL for the Auth 2.0 authentication form - I took a glance also on Spring Dataflow main repository (backend) and found a .adoc file ( see /spring-dataflow-docs/src/main/asciidoc/configuration.adoc line 747 ) where this redirect is specified.

klopfdreh commented 2 years ago

Yes but the default redirection {baseUrl}/login/oauth2/code/{registrationId} points to the scdf server itself. I guess it is the default login page of Spring Security OAuth2 / Spring Security.

claudiahub commented 2 years ago

Yep, same guess on my side. So I believe this same issue should be moved to Spring Security.

klopfdreh commented 2 years ago

Found it (I guess) - the class is called LoginPageGeneratingWebFilter and it includes Bootstrap CSS here:

https://github.com/spring-projects/spring-security/blob/ea777a3d7b335eb37dcb4605595220d931703ca5/web/src/main/java/org/springframework/security/web/server/ui/LoginPageGeneratingWebFilter.java#L98

It is also responsible for OAuth2 authentication, because it provides setOauth2AuthenticationUrlToClientName:

https://github.com/spring-projects/spring-security/blob/ea777a3d7b335eb37dcb4605595220d931703ca5/web/src/main/java/org/springframework/security/web/server/ui/LoginPageGeneratingWebFilter.java#L59

and it matches /login:

https://github.com/spring-projects/spring-security/blob/ea777a3d7b335eb37dcb4605595220d931703ca5/web/src/main/java/org/springframework/security/web/server/ui/LoginPageGeneratingWebFilter.java#L49

Edit: Use permanent links at references.

Maybe it would be good to create a custom login form that also uses the login page of the SCDF and Angular: https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/form.html

When you click on logout, then you are redirected to a login page which is styled with Spring Cloud Data Flow lookup. The only thing which has to be adjusted would be to show the registrations like mentioned here, because there can be several: https://docs.spring.io/spring-cloud-dataflow/docs/current/reference/htmlsingle/#configuration-security-oauth2

So basically if you only provide OAuth2 as authorization standard create a form that is created the same way as in this method:

https://github.com/spring-projects/spring-security/blob/ea777a3d7b335eb37dcb4605595220d931703ca5/web/src/main/java/org/springframework/security/web/server/ui/LoginPageGeneratingWebFilter.java#L140

Last edit: I don't think this is an Spring Security issue, because they only provide a Default-Implementation. I guess the customization should be in Spring Cloud Data Flow and should not use Bootstrap but Angular as presentation layer.

claudiahub commented 2 years ago

Exactly. I found the same files on the Spring Security repository.

I see clearly they're injecting there the bootstrap minified css.

klopfdreh commented 2 years ago

So based on the things we found out I would suggest:

  1. Configure the backend to show a custom login form as mentioned in my previous commit and by the documentation of Spring Security
  2. Create new Rest Endpoints to provide the required authorization data like registrations and so on to the Angular frontend
  3. Create a new folder in spring-cloud-data-flow-ui called login and place in there the pages to be shown at login which are using the data from the rest endpoints.

Because it is a login page, it should be excluded from redirection to the login page from the UI. Also be aware of CSRF Tokens which are checked by Spring Security.

the good thing is that you have full control over the appearance of the login and you can design it the SCDF-way.

onobc commented 2 years ago

Thanks for the analysis and suggested plan @klopfdreh . I am marking this for team meeting and we will discuss further. I will keep you posted on the direction w/ an update here in this ticket.

klopfdreh commented 2 years ago

Thanks again! 😀 I guess it is a mediocre effort but improves the appearance a lot. If I can assist just let me know.

claudiahub commented 2 years ago

Spring security referenced issue https://github.com/spring-projects/spring-security/issues/11949

corneil commented 2 years ago

We believe the simplest solution would be is to change the styling to use the same CSS styling as the rest of the application and remove any dependance on Bootstrap.

klopfdreh commented 2 years ago

Hey @corneil - just want to mention that you can only style the login yourself if you create a custom login page - otherwise you can not get CSS into the page because it is rendered by Spring Security.

But if there is any way I would be very interested in learning how to do so.

oodamien commented 2 years ago

From my understanding, we have to customise Spring Security Settings (create a custom login page). This should be on the server side. @corneil We don't need to import all the App CSS. A simple CSS file should be enough.

corneil commented 2 years ago

Investigating options for customising login page while remaining compatible with Spring Security variations without replicating all of Spring Security Filters etc.

klopfdreh commented 2 years ago

Investigating options for customising login page while remaining compatible with Spring Security variations without replicating all of Spring Security Filters etc.

Great! Thanks a lot for all the effort. May I don't know all places which are relevant for those changes, but I think this would be a good place: https://github.com/spring-cloud/spring-cloud-dataflow/blob/main/spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/config/DataflowOAuthSecurityConfiguration.java - in here you can permit all requests to the login page /login like:

http.authorizeRequests().antMatchers("/login*").permitAll();

Because the context path is also included in this pattern as it only means / with context root - this should work. As I saw here: https://docs.spring.io/spring-cloud-dataflow/docs/current/reference/htmlsingle/#configuration-security-oauth2 - As of Spring Cloud Data Flow 2.0, OAuth2 is the only mechanism for providing authentication and authorization. so I guess there are no other login scenarios to cover.

Further more it would be great when this login screen could be used:

image

I created a prototype:

image

This login page is shown when I press logout in the Spring Cloud Data Flow UI and is already styled in a nice way.

onobc commented 1 year ago

@klopfdreh this did not fit into the current release candidate. However, we will pursue this issue as one of the high priority items post 2.10.0.

klopfdreh commented 1 year ago

@onobc all right! Thanks for the information!