404 with response.sendRedirect - java

I am using spring security login mechanism for my application and tested everything.Things were working fine.I have the following use case
If customer is not logged in , application will redirect customer to the login page.
On successful login, application will redirect customer back to same page from where they were redirected to the login page
this is the Java code used to redirect user to his original location
final SavedRequest savedRequest = this.requestCache.getRequest(request, response);
targetUrl = savedRequest.getRedirectUrl();
getRedirectStrategy().sendRedirect(request, response, targetUrl);
RedirectionStrategy being used here is DefaultRedirectStrategy, things were working fine. Application is now deployed on the Pre Production server and now this seems not working and I am getting 404 error.
When customer is being redirected to the home page,targetUrl is coming out as "/", I have a Spring controller named with this mapping
#RequestMapping("/")
public class HomePageController{ // home page code }
my application's current Pre-Prod urs is prepd-www.mysite.com so when sendredirect come in to action, webpage URL is getting changed to prepd-www.mysite.com/prepd-www.mysite.com
I am not sure what is causing this issue. is it because of the proxy server settings ?
Can any one suggest me about the possible root cause of this issue?
I have already tried it on all local machines and well on our QA but everything is working perfectly fine.
Current setup for the environment where this is happening is
We have 4 app server
We have one load balancer which is redirecting traffic to one of the app server.

Just a wild guess since you could not give the reverse proxy configuration, nor the exact URL used in pre prod and in developpement.
You say you are using DefaultRedirectStrategy from Spring security. This strategy has an option (contextRelative) that prepends the ServletContext path to the URL. If in your developpement system you were using the root context, that is if you were accessing home page at (for example) : http://localhost:8080/ the serlet context was empty.
But if now in preprod, the servlet context is no longer root but is say /myApp once translated by apache reverse proxy, when you redirect you get an URL of /myApp/myApp that could be translated back to what you gave.
You could try to control whether you have contextRelative as true in DefaultRedirectStrategy and if yes if you can set if to false and also control if you redirect to absolute or relative URLs.

If you are using apache in front check rewrite rule and redirect rules of apache config. Best way would be to ssh tunnel directly to application server(by skipping apache) and test. If it's working that means your application config is fine and it needs to be fixed in apache.

Are you using in preproduction tomcat or another application server?, normally if your war is calling foo and your commit to tomcat, the path for this war is
http://localhost:8080/foo/
So if you are using servlet you need specify in your web.xml that the main path is foo/*

Related

Using relative redirect in spring boot fails

Scenario
I have an spring-boot application which is accessed using context instead domain root:
domain root : http://app.com
my app : http://app.com/organization_a (redirects me to my app login)
my app login : http://app.com/organization_a/login (form is loaded perfectly)
Problem
After success login, using the classic configuration:
formLogin()
.loginPage("/login")
.defaultSuccessUrl("/my_form")
redirects me to : http://app.com/my_form throwing an error because the url must be : http://app.com/organization_a/my_form
So, I tried to use relative url (note the dot before /my_form) ./my_form instead /my_form
formLogin()
.loginPage("/login")
.defaultSuccessUrl("./my_form")
And spring throw me this error : defaultTarget must start with '/' or with 'http(s) due to this validation in spring-security-web jar:
//org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler
public void setDefaultTargetUrl(String defaultTargetUrl) {
Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultTargetUrl),
"defaultTarget must start with '/' or with 'http(s)'");
this.defaultTargetUrl = defaultTargetUrl;
}
So, I can say: Classic default success url method does not allow to use relative urls, because if I use root domain , works like charm as in my localhost.
Relative vs Absolute urls
More info here
I had similar troubles with html and assets in java an other languages like php and nodejs.
Basically if you are using context instead a domain root for your app, you must need to change this:
<link href="/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"/>
to
<link href="./vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"/>
Note the dot before /vendor/bootstrap/...
Without this dot, your assets will not download because the browser request to urls like :
http://app.com/main.css
http://app.com/app.js
When should it be:
http://app.com/organization_a/main.css
http://app.com/organization_a/app.js
Current workarounds
Use domain or subdomain instead context.
This is laborious because I will need to open a ticket to my ISP for every new app.
Put the entire url in defaultSuccessUrl method.
This is awful because my app will not be portable due to I must set the absolute url before build:
formLogin()
.loginPage("/login")
.defaultSuccessUrl("http://app.com/organization_a/my_form")
Question
Is there a way to use relative redirect in spring security?
I am using one of the latest spring boot versions: 2.1.7.RELEASE
Any help or comment are appreciated.
Thanks
I managed to enable relative redirects via the following spring properties:
server:
tomcat:
use-relative-redirects: true

Abnormal Behaviour of Web Browser

I was working on a Spring-security LDAP application. I'm following the link - https://spring.io/guides/gs/authenticating-ldap/ . Problem I'm facing is that I have made a very simple controller and a method to handle a request, returning a string. But browser is opening a login page (which I can't find anywhere). I deleted cache, restarted Eclipse and system both but to my dismay it displays the same page irrespective of any url configured in controller or any port. I'm unable to elucidate this behavior of browser.
If you had followed the guide exactly as it is, then you may notice that the file WebSecurityConfig.java has the following line http.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and().formLogin(); Which means that all your requests need to be authenticated. That means any end points that you define need to be authenticated too. They are secured by default.
You seem to have made a GET request to your endpoint, which is secured by Spring Security. If you want to create an unsecure endpoint then you have to make changes to the WebSecurityConfig file.
The login page that you mention is provided by Spring security library itself. It won't be available in your cloned project. At the end of the page they have also mentioned that the username is ben and password is benspassword. Spring security provides lot of default options which are useful. But, unless you read the documentation to understand what they are, you are in for quite a few surprises.

Angular 2 application deployed on JBOSS 6.4 eap with java services as backend

Problem 1: Angular 2 application deployed on JBOSS server but not able to load static content (js/css). The problem is the website is hosted under its own context (localhost:8080/sample/) and static resources is refered in index.html as (link href="css/index.css" rel="stylesheet") however it doesnt get loaded as network calls are made to localhost:8080/css/index.css.
I need it to point to localhost:8080/sample/css/index.css
Problem 2: Alternately we tried hosting angular application on tomcat but services need to be hosted on jboss, we tried implementing CROS filter (https://amodernstory.com/2014/12/27/using-cors-headers-with-java-example/) but the first request goes through but other request shows pending status in Chrome network's tab.
I'm having the same problem. To get it to load the static content, you need to set the base href inside index.html to "./". I have found that "." also works. The application should then load properly, BUT you will run into another problem: if you try to visit any of the application routes directly using the address bar, you will see "Not Found". This seems to be related to JBoss's ability to rewrite HTML5 URLs and redirect them to the index. I am trying to solve that problem using the information on this page: https://issues.jboss.org/browse/JDF-512. I will let you know if I succeed.
You can create an index.prod.html with the correct references to "/sample/css/index.css". Then add the following in the angular.json
"production": {
"fileReplacements": [
{
"replace": "src/index.html",
"with": "src/index.prod.html"
}

Spring security: using relative path

I have an application with name test.war.
Because of Apache installed on my server I have to use another port number for Tomcat applications so after deployment this application available at domain.com:8080/test/.
I decided to create a subdomain in order to remove that ugly 8080 from url, so I setted up the server like described here. So now test.domain.com reffers to domain.com:8080/test/.
Everything seems fine except of one problem - because my application is not ROOT.war and I am using spring:url function every url in the application is translated to /test/bla-bla. So I removed that function. But still have a problem with spring security because it still translates an urls relative to app name i.e. /test/bla-bla.
How can I solve that problem?
Thank you
UPD: I don't want to deploy it as a ROOT application because I have two or three such applications and I wanted to create a subdomain for each one of them
Spring Security doesn't "translate" URLs. In fact this isn't specific to Spring Security. You'll run into similar issues with any application which does redirects. If you want to hide the context paths of applications which are behind a proxy, then you need to rewrite the URLs at the proxy.
I'd recommend you read the Tomcat Generic Proxy Howto and the section on URL rewriting in particular, as it specifically addresses this issue.

Login session lost after flex chart is displayed from jsp

I have a java web application. When I log in to that application and navigate to a jsp which has flex chart embeded into it, the chart displayes just fine. I am using blaze ds remoting object mechanism. But when I want to navigate to a different page, it logs me out of application since the login session is lost.
The HTTP session is backed by a HTTP cookie which is tied to a specific domain and by default also the context path. So if you lose the session, then it may be caused by navigating to a different domain and/or context path. It's however also possible to invalidate the session programmatically by calling HttpSession#invalidate().
So to fix your problem, you need to ensure that you're navigating to a page in the same domain and context and that your server side code is not unnecessarily calling invalidate() somewhere.
If the problem is actually caused by a switch in the context path and you'd like to get it fixed, then you need to configure it in the servletcontainer. It's unclear which one you're using, but in for example Apache Tomcat you would like to set the emptySessionPath attribute of the <Connector> element in /conf/server.xml to true. Also see this document.

Categories