Tomcat prefix to every Spring url with Spring Security - java

Currently I'm facing issue with redirecting application which is behind proxy server:
To see application I need to go to:
http://myserver.net/PREFIX/configuration
And I need to add PREFIX to every url which will be returned by spring. Currently after successful logging with spring security when I return
.successForwardUrl("/configuration")
It's redirecting me to url address which is not existing:
http://myserver.net/configuration
Is there any possibility to add Tomcat prefix to dispatcher servlet? To make somehow default path for the application:
http://myserver.net/PREFIX/
I was trying to use:
server.servlet.contextPath=PREFIX
But problem is that when I use context path, I need to go
http://myserver.net/PREFIX/PREFIX/configuration
To be redirected properly to spring controller. Maybe there is possibility to set up context path but only for response?

Related

Spring Boot/Auth0 - How do I specify the connection?

I am working on setting up an application using Spring Boot and Auth0. We are refactoring from a legacy codebase to use Spring Boot. In the legacy code, the Auth0 URL is created manually by appending the URL parameters:
https://[removed].auth0.com/authorize?
response_type=code
&client_id=[removed]
&scope=openid email profile
&connection=[removed]
&state=[removed]
&redirect_uri=http://localhost:8081/login/oauth2/code/auth0
With the Spring Boot configuration (guide here: https://auth0.com/docs/quickstart/webapp/java-spring-boot/01-login), this is the URL that generates:
https://[removed].auth0.com/authorize?
response_type=code
&client_id=[removed]
&scope=openid email profile
&state=[removed]
&redirect_uri=http://localhost:8081/login/oauth2/code/auth0
The Spring Boot URL is giving me an error "[invalid_request] no connections enabled for the client".
I am missing the "connection" parameter with the Spring Boot setup. I have tested by manually copying the URL and adding the "connection" parameter and I get the login page. Without it, I get the error.
On Spring's configuration page (https://docs.spring.io/spring-security/reference/servlet/oauth2/login/core.html#oauth2login-boot-property-mappings), I don't see an option for Connection. I didn't see anything on the SecurityFilterChain that would allow me to change this either.
I see that Auth0.js has a function that allows a "connection" parameter (https://auth0.com/docs/libraries/auth0js). How do I add this using Spring Boot/Java?
EDIT
application.properties:
spring.security.oauth2.client.registration.auth0.client-id=[removed]
spring.security.oauth2.client.registration.auth0.client-secret=[removed]
spring.security.oauth2.client.registration.auth0.scope[0]=openid
spring.security.oauth2.client.registration.auth0.scope[1]=email
spring.security.oauth2.client.registration.auth0.scope[2]=profile
spring.security.oauth2.client.provider.auth0.issuer-uri=[removed]
EDIT 2
We were working in conjunction with Auth0 Support - they provided us the following information:
In case an Enterprise connection is the only enabled connection for an
application and the "connection" parameter is not specified on the
/authorize request, you need to enable the "show as a button" setting
on that enterprise connection, otherwise you will get "no connections
enabled for the client" error.
The "Display connection as a button" checkbox is on the "Login
Experience" tab of the connection setting page.
Weird configuration requirement - you can't go directly to the login page. You have to have a button to take you there. This did resolve the original issue; however, I marked #Codo answer below as accepted, as it did answer this question and appears it would work from initial testing.
You are looking for a way to add an additional parameter to the authorization URI. It's isn't as straightforward as one would like but doable.
Fortunately, it's described in Customizing Authorization and Token Requests with Spring Security 5.1 Client.
You probably want to implement the steps 2 and 4:
Add your own implementation of OAuth2AuthorizationRequestResolver, override both resolve() methods to call customizeAuthorizationRequest()
Implement customizeAuthorizationRequest() to add the additional connection parameter (OAuth2AuthorizationRequest already support additional parameters)
Implement a security configuration class to register CustomAuthorizationRequestResolver as the authorization request resolver
Several issues on GitHub ask for a simpler way. But the issues are still open (or closed as duplicates).
Update
Instead of clientRegistrationRepository() (at the end of step 2), you could declare clientRegistrationRepository as an injected dependency and the use it without parentheses:
#Autowired
private ClientRegistrationRepository clientRegistrationRepository;
Spring Security comes with with mostly preconfigured Auth0 module. Unless you're doing something specific, there's no need to construct URL yourself.
Have you done Spring configuration as said in the link you've posted: https://auth0.com/docs/quickstart/webapp/java-spring-boot/01-login#configure-spring-security ?
# src/main/resources/application.yml
spring:
security:
oauth2:
client:
registration:
auth0:
...
Here's another option (untested):
In application.properties, specify all URLs separately. So instead of:
spring.security.oauth2.client.provider.auth0.issuer-uri=xyz.us.auth0.com
Specify:
spring.security.oauth2.client.provider.auth0.authorization-uri=https://xyz.us.auth0.com/authorize?connection=azuread
spring.security.oauth2.client.provider.auth0.token-uri=https://xyz.us.auth0.com/oauth/token
spring.security.oauth2.client.provider.auth0.jwk-set-uri=https://xyz.us.auth0.com/=.well-known/jwks.json
spring.security.oauth2.client.provider.auth0.user-info-uri=https://xyz.us.auth0.com/userinfo
Note that the authorization URI already includes the connection parameters. All the other parameters should then be appended.
You can get all the URIs at https://xyz.us.auth0.com/.well-known/openid-configuration (just replace "xyz" and put the URL in your browser).

Difference in URLs to access the Controller Mappings

I am trying to learn Spring Framework and while going through the Spring MVC and Spring Boot REST to create a dummy project, I noticed below difference in the way the Tomcat responds to your URL in the browser
Spring Boot
http://localhost:8080/
Redirects to the Controller that is mapped to "/"
http://localhost:8080/springbootrestapp
where "springbootrestapp" is the project name, it gives HTTP 404 resource not found error
Spring MVC
http://localhost:8080/
Opens the Tomcat Home page
http://localhost:8080/springmvc
where "springmvc" is the project name, it redirects to the Controller that is mapped to "/"
My doubt is why in case of Spring Boot just entering the localhost:8080 redirects to the controller mapped to "/" whereas in case of Spring MVC(without Spring Boot configurations) it needs http://localhost:8080/<projectname>/ to redirect to controller mapped to "/" ?
I got the same issue In my case before running my Spring-MVC application I started the tomcat server I didn't stop so whenever I access localhost:8080/ it redirect me to Tomcat Client.
The first option is very basic: we just have to delete the /ROOT/ folder in $CATALINA_HOME\webapps, rename our springbootrestapp.war (or springmvc.war) to ROOT.war, and deploy it.
Our app will now be available at http://localhost:8080/.
There are different solutions not to change the filename. You can review the recommendations here.

how do I make spring boot embedded tomcat to return 200 OK for base url?

My app is deployed at http://123.87.65.23:8080. The context path is /myapp configured in application.properties. So if I access http://123.87.65.23:8080, I get 404. but if I access http://123.87.65.23:8080/myapp/health, I get 200 as expected.
Our operation team monitors base url (http://123.87.65.23:8080) for 200 OK.
I have two options:
Return 200 OK when I hit http://123.87.65.23:8080. No response is required.
Or somehow proxy the request http://123.87.65.23:8080 to http://123.87.65.23:8080/myapp/health within my Spring Boot application.
NOTE: I am using embedded tomcat. so the option of changing server.xml is not applicable
I don't how know how to do either options.
If you set the contextPath attribute in your .properties file then Spring does what it's supposed to do, everything gets moved there.
If you're packaging the app as a .war and running it in an external server then you can set that server up to redirect root requests to whatever URL inside your Spring Boot application.
If you're packaging the app as a runnable .jar with an embedded server and you want to keep the contextPath in the .properties-level then
a) you still need some kind of external server that can catch requests to root and redirect to your Spring Boot application
b) you need to set up two distinct DispatcherServlets where one's contextPath is /myapp and the other's is / which will redirect to your Spring Boot Application
However, the easiest solution would be to remove contextPath and just prepend each Controller's #RequestMapping with /myapp, move all the management endpoints to /myapp with management.context-path and write a single #Controller method mapped to / that redirects to the health endpoint.
In your tomcat container your app should be deployed into a directory named "ROOT", not "myapp", if you wanna use root urls. And I guess your Dispatcherservlet may be configured to process requests to /health, and you need to process just /
Or maybe you've got a Controller, mapped to /health.
Can't tell anything else without code
If you want to get 200 on http://123.87.65.23:8080 request, you need an application named ROOT.war in your webapps folder.
So http://123.87.65.23:8080 and http://123.87.65.23:8080/myapp are two different applications.
I suggest you two options:
Deploy your application as http://123.87.65.23:8080 (ROOT.war)
Use some Proxy Server like nginx or apache. You can configure the proxy server to redirect all ROOT requests to you application
Here are some examples for nginx:
location / {
proxy_pass http://123.87.65.23:8080/myapp/;
}
or just return 200:
location / {
return 200;
}

Spring #RequestMapping redirect to same path with additional info

A somewhat unusual scenario perhaps, but we need to redirect in a Spring MVC controller from:
/js/hal-browser/browser.html
to:
/js/hal-browser/browser.html#/some_path/
All my attempted solutions to date have resulted in a redirect loop, as Spring performs the redirect but is then repeatedly matching /browser.html in the redirect URL, regardless of the additional info. What I need to say is 'match /browser.html ONLY if it's the end of the path'.
I have tried setUseSuffixPatternMatch(Boolean.FALSE); on the PathMatchConfigurer to no avail, also tried the following URI template regex pattern in the request mapping itself:
"/js/hal-browser/{file:browser\\.html$}"
..but still get a redirect loop. Ideas appreciated - this is Spring 4.1.6 in a SpringBoot 1.2.3 microservice, by way of context.
Update:
On further investigation and a better understanding of the URL fragment in use by the HAL browser to determine which path it will make a request to within the microservice itself, I believe the solution may lie not in trying to redirect off browser.html, as Spring will map this to the same controller method on every request regardless of the fragment value, but instead either reverting to the default context path for the application (/), which the HAL browser has set as its default entry point, or finding a way to configure the embedded tomcat container to respond with something sensible (not just a 404) on the default context path even though the app is mapped to /some_path.
As further context, we can redirect no problem at all from a convenience path of /browser (or whatever) into the HAL browser with the correct entry point fragment as the context path of the service - that works fine. The issue is the browser itself has a 'Go to entry point' button which, when pulling it in as a webjar, is hardcoded to /. The other alternative is to ditch the webjar and just copy in the static files for the browser and update the entry point.
The part after the # will never be sent to the server so in this case you'll always end-up with the same request within the loop.
What you can do is add a custom header in your controller, and make your controller intercept only the code where the header is not present by using the negation of the headers attribute, here's a pseudo code
#RequestMapping(value=[YOUR MAPPING], method=RequestMethod.GET, headers="!CustomHeader")
You could try not redirecting the user, but sending back the content you intended with some javascript to make the client browser to jump to the anchor on the after it loads, e.g. something like:
window.location.hash="/some_path/";

Spring MVC application context path

My Spring MVC application is runnning on a Tomcat behind an Apache 2 acting as a proxy. I access my app directly in tomcat via an url like http://localhost:8080/myapp. I access my app via proxy with an url like http://localhost/tomcat/myapp.
The second url makes my app behave incorrectly, because it supposes it lives in /myapp context path, but via the proxy it should live in /tomcat/myapp.
Is there a variable in Spring or Servlet API, that holds /tomcat/myapp if I am accessing it via the proxy, and /myapp if I am accessing it directly?
Thanx
I think you need to enable proxy support then. This link might help you or give a little hint in this regards.
http://tomcat.apache.org/tomcat-6.0-doc/proxy-howto.html
Just stumbled upon this post while searching for the config setting for tomcat.
There is a much easier way to configure tomcat to handle the exact situation you are experiencing. See:
http://tomcat.apache.org/tomcat-5.5-doc/proxy-howto.html
Simple configure a connector for the proxy in tomcat, and the servlet/struts context path issues will resolve.
-edit: Obviously I didn't read #2 comment...
I mean when I redirect to "/index.jsp"
it actually redirects to
"http://localhost/myapp/index.jsp"
instead of
"http://localhost/tomcat/myapp/index.jsp"
Redirect to index.jsp instead of /index.jsp
When you redirect to /index.jsp this acts as an absolute url and it gets redirected to myapp/index.jsp. index.jsp is a relative url and will redirect to tomcat/myapp/index.jsp

Categories

Resources