问题描述
场景
我有一个使用上下文而不是域根访问的 spring-boot 应用程序:
- 域根:http://app.com
- 我的应用:http://app.com/organization_a(将我重定向到我的应用登录)
- 我的应用登录:http://app.com/organization_a/login(表单已加载完美)
问题
登录成功后,使用经典配置:
formLogin().loginPage("/登录").defaultSuccessUrl("/my_form")
将我重定向到:http://app.com/my_form 抛出错误,因为网址必须是:http://app.com/organization_a/my_form
所以,我尝试使用相对 url(注意/my_form 之前的点)./my_form 而不是 /my_form
formLogin().loginPage("/登录").defaultSuccessUrl("./my_form")
Spring 向我抛出此错误:defaultTarget 必须以/"或http(s) 开头,因为在 spring-security-web jar 中进行了此验证:
//org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandlerpublic void setDefaultTargetUrl(String defaultTargetUrl) {Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultTargetUrl),"defaultTarget 必须以'/' 或'http(s)' 开头");this.defaultTargetUrl = defaultTargetUrl;}
所以,我可以说:经典的默认成功 url 方法不允许使用相对 url,因为如果我使用 root domain ,就像在我的本地主机中一样魅力.
相对网址与绝对网址
更多信息此处
我在 java 中的 html 和资产以及其他语言(如 php 和 nodejs)方面遇到了类似的问题.
基本上,如果您为应用程序使用上下文而不是域根目录,则必须进行更改:
到
注意/vendor/bootstrap/... 之前的点
如果没有这个点,您的资产将无法下载,因为浏览器请求的网址如下:
应该什么时候:
当前的解决方法
- 使用域或子域代替上下文.
- 这很费力,因为我需要为每个新应用打开一个到我的 ISP 的票.
- 将整个 url 放入 defaultSuccessUrl 方法中.
- 这很糟糕,因为我必须在构建之前设置绝对网址,因此我的应用程序将不可移植:
formLogin().loginPage("/登录").defaultSuccessUrl("http://app.com/organization_a/my_form")
问题
有没有办法在 Spring Security 中使用相对重定向?
我使用的是最新的 Spring Boot 版本之一:2.1.7.RELEASE
感谢任何帮助或评论.
谢谢
我设法通过以下 spring 属性启用了相对重定向:
服务器:雄猫:使用相对重定向:true
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;
}
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 :
When should it be:
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
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
这篇关于在 Spring Boot 中使用相对重定向失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!