aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2022-12-07 16:13:57 +0300
committerGravatar Vitaly Takmazov2022-12-07 17:38:55 +0300
commit5e0500933d2f805fe879ced9171c65839c72579b (patch)
tree60eeb84ac103c3f160dda3c2adbd1a10c489e8ec /src
parent206742aed99a20fea014c83408fb44ff36089351 (diff)
Login: use `Referer` header to redirect after the successful login
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/juick/config/SecurityConfig.java36
-rw-r--r--src/main/java/com/juick/www/SiteAttributesHandler.java (renamed from src/main/java/com/juick/www/VaryHandler.java)8
-rw-r--r--src/main/java/com/juick/www/controllers/Site.java15
-rw-r--r--src/main/resources/templates/views/login_success.html13
-rw-r--r--src/main/resources/templates/views/partial/navigation.html2
-rw-r--r--src/test/java/com/juick/server/tests/ServerTests.java4
6 files changed, 42 insertions, 36 deletions
diff --git a/src/main/java/com/juick/config/SecurityConfig.java b/src/main/java/com/juick/config/SecurityConfig.java
index f93e12a8..b16dc755 100644
--- a/src/main/java/com/juick/config/SecurityConfig.java
+++ b/src/main/java/com/juick/config/SecurityConfig.java
@@ -34,7 +34,9 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.RememberMeServices;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
@@ -126,30 +128,45 @@ public class SecurityConfig {
BasicAuthenticationFilter.class)
.authorizeHttpRequests(requests -> requests
.requestMatchers(HttpMethod.OPTIONS).permitAll()
- .requestMatchers("/api/", "/api/messages", "/api/avatar", "/api/messages/discussions",
- "/api/users", "/api/thread", "/api/tags", "/api/tlgmbtwbhk", "/api/fbwbhk",
- "/api/skypebotendpoint", "/api/_fblogin", "/api/_vklogin", "/api/_tglogin",
- "/api/_google", "/api/_applelogin", "/api/signup", "/api/inbox", "/api/events",
+ .requestMatchers("/api/", "/api/messages", "/api/avatar",
+ "/api/messages/discussions",
+ "/api/users", "/api/thread", "/api/tags",
+ "/api/tlgmbtwbhk", "/api/fbwbhk",
+ "/api/skypebotendpoint", "/api/_fblogin",
+ "/api/_vklogin", "/api/_tglogin",
+ "/api/_google", "/api/_applelogin", "/api/signup",
+ "/api/inbox", "/api/events",
"/api/info/**",
"/api/nodeinfo/2.0")
.permitAll()
.anyRequest().hasRole("USER"))
.anonymous(anonymous -> anonymous.principal(JuickUser.ANONYMOUS_USER)
.authorities(JuickUser.ANONYMOUS_AUTHORITY))
- .httpBasic(httpBasic -> httpBasic.authenticationEntryPoint(juickAuthenticationEntryPoint()))
+ .httpBasic(httpBasic -> httpBasic
+ .authenticationEntryPoint(juickAuthenticationEntryPoint()))
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
- .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
- .exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint(juickAuthenticationEntryPoint()))
+ .sessionManagement(sessionManagement -> sessionManagement
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .exceptionHandling(exceptionHandling -> exceptionHandling
+ .authenticationEntryPoint(juickAuthenticationEntryPoint()))
.csrf().disable()
.headers().defaultsDisabled().cacheControl();
return http.build();
}
@Bean
+ public AuthenticationSuccessHandler successHandler() {
+ SimpleUrlAuthenticationSuccessHandler handler = new SimpleUrlAuthenticationSuccessHandler();
+ handler.setUseReferer(true);
+ return handler;
+ }
+
+ @Bean
public SecurityFilterChain wwwChain(HttpSecurity http) throws Exception {
http.addFilterBefore(wwwAuthenticationFilter(), BasicAuthenticationFilter.class)
.authorizeHttpRequests(authorize -> authorize
- .requestMatchers("/settings", "/pm/**", "/**/bl", "/_twitter", "/post", "/post2",
+ .requestMatchers("/settings", "/pm/**", "/**/bl", "/_twitter", "/post",
+ "/post2",
"/comment")
.authenticated()
.requestMatchers("/actuator/**").hasRole("ADMIN")
@@ -168,10 +185,9 @@ public class SecurityConfig {
.logoutSuccessUrl("/")
.deleteCookies("hash", COOKIE_NAME))
.formLogin(form -> form.loginPage("/login")
- .defaultSuccessUrl("/")
- .loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
+ .successHandler(successHandler())
.failureUrl("/login?error=1")
.permitAll())
.csrf(csrf -> csrf.ignoringRequestMatchers("/settings/unsubscribe", "/h2-console/**"))
diff --git a/src/main/java/com/juick/www/VaryHandler.java b/src/main/java/com/juick/www/SiteAttributesHandler.java
index 6910823d..e06a2070 100644
--- a/src/main/java/com/juick/www/VaryHandler.java
+++ b/src/main/java/com/juick/www/SiteAttributesHandler.java
@@ -17,15 +17,21 @@
package com.juick.www;
+import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import jakarta.servlet.http.HttpServletResponse;
@ControllerAdvice
-public class VaryHandler {
+public class SiteAttributesHandler {
@ModelAttribute
public void setVaryResponseHeader(HttpServletResponse response) {
response.setHeader("Vary", "Accept-Language");
}
+ @ModelAttribute
+ public void setReturnPathAttribute(Model model) {
+ model.addAttribute("retpath", ServletUriComponentsBuilder.fromCurrentRequestUri().toUriString());
+ }
}
diff --git a/src/main/java/com/juick/www/controllers/Site.java b/src/main/java/com/juick/www/controllers/Site.java
index a0b8c5b0..aa6d574d 100644
--- a/src/main/java/com/juick/www/controllers/Site.java
+++ b/src/main/java/com/juick/www/controllers/Site.java
@@ -46,6 +46,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.inject.Inject;
import java.net.URLEncoder;
@@ -96,10 +97,12 @@ public class Site {
}
@GetMapping("/login")
- public String getloginForm(@Visitor User visitor, HttpSession session,
- @RequestParam(required = false, defaultValue = "true") boolean redirect, ModelMap model) {
+ public String getloginForm(@Visitor User visitor,
+ @RequestParam(name = "retpath", required = false, defaultValue = "/") String retPath,
+ HttpSession session,
+ ModelMap model) {
if (!visitor.isAnonymous()) {
- return redirect ? "redirect:/" : "redirect:/login/success";
+ return String.format("redirect:%s", retPath);
}
model.addAttribute("visitor", visitor);
model.addAttribute("tags", tagService.getPopularTags());
@@ -119,12 +122,6 @@ public class Site {
return "views/login";
}
- @GetMapping("/login/success")
- public String getSuccessLogin(@Visitor User visitor, ModelMap model) {
- model.addAttribute("hash", userService.getHashByUID(visitor.getUid()));
- return "views/login_success";
- }
-
@GetMapping("/")
protected String doGet(@Visitor User visitor, Locale locale, @RequestParam(required = false) String tag,
@RequestParam(name = "show", required = false) String paramShow,
diff --git a/src/main/resources/templates/views/login_success.html b/src/main/resources/templates/views/login_success.html
deleted file mode 100644
index ee71f12f..00000000
--- a/src/main/resources/templates/views/login_success.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <title>Blank window</title>
-</head>
-<body>
- <script type="text/javascript">
- window.opener.postMessage("{{ hash }}", "*");
- window.close();
- </script>
-</body>
-</html>
diff --git a/src/main/resources/templates/views/partial/navigation.html b/src/main/resources/templates/views/partial/navigation.html
index 184c8f2b..159c3d21 100644
--- a/src/main/resources/templates/views/partial/navigation.html
+++ b/src/main/resources/templates/views/partial/navigation.html
@@ -33,7 +33,7 @@
<span class="icon-title desktop">{{ i18n("messages","link.postMessage") }}</span>
</a>
{% else %}
- <a class="a-login" href="/login" rel="nofollow">
+ <a class="a-login" href="/login?retpath={{ retpath | default('/') }}" rel="nofollow">
<i data-icon="ei-user" data-size="s"></i>
<span class="icon-title desktop">{{ i18n("messages", "link.Login") }}</span>
</a>
diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java
index b40cbc04..367b8e47 100644
--- a/src/test/java/com/juick/server/tests/ServerTests.java
+++ b/src/test/java/com/juick/server/tests/ServerTests.java
@@ -1959,9 +1959,9 @@ public class ServerTests {
Cookie rememberMeFromForm = formLoginResult.getResponse().getCookie("juick-remember-me");
mockMvc.perform(get("/login").cookie(rememberMeFromForm)).andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/"));
- mockMvc.perform(get("/login?redirect=false").cookie(rememberMeFromForm))
+ mockMvc.perform(get("/login?retpath=http://localhost:8080/logged_in").cookie(rememberMeFromForm))
.andExpect(status().is3xxRedirection())
- .andExpect(redirectedUrl("/login/success"));
+ .andExpect(redirectedUrl("http://localhost:8080/logged_in"));
}
@Test