Merge pull request #9476 from cicioflaviu/master

BAEL-4018 Spring Security - Already logged in user redirect from the login page
This commit is contained in:
rpvilao 2020-07-06 10:09:59 +01:00 committed by GitHub
commit d88b074601
8 changed files with 240 additions and 0 deletions

View File

@ -0,0 +1,43 @@
package com.baeldung.loginredirect;
import org.apache.http.HttpStatus;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
class LoginPageFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse) response;
if (isAuthenticated() && "/loginUser".equals(servletRequest.getRequestURI())) {
String encodedRedirectURL = ((HttpServletResponse) response).encodeRedirectURL(
servletRequest.getContextPath() + "/userMainPage");
servletResponse.setStatus(HttpStatus.SC_TEMPORARY_REDIRECT);
servletResponse.setHeader("Location", encodedRedirectURL);
}
chain.doFilter(servletRequest, servletResponse);
}
private boolean isAuthenticated() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || AnonymousAuthenticationToken.class.isAssignableFrom(authentication.getClass())) {
return false;
}
return authentication.isAuthenticated();
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.loginredirect;
import org.apache.http.HttpStatus;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.UrlPathHelper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
class LoginPageInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
if ("/loginUser".equals(urlPathHelper.getLookupPathForRequest(request)) && isAuthenticated()) {
String encodedRedirectURL = response.encodeRedirectURL(
request.getContextPath() + "/userMainPage");
response.setStatus(HttpStatus.SC_TEMPORARY_REDIRECT);
response.setHeader("Location", encodedRedirectURL);
return false;
} else {
return true;
}
}
private boolean isAuthenticated() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || AnonymousAuthenticationToken.class.isAssignableFrom(authentication.getClass())) {
return false;
}
return authentication.isAuthenticated();
}
}

View File

@ -0,0 +1,13 @@
package com.baeldung.loginredirect;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource({"classpath*:spring-security-login-redirect.xml"})
class LoginRedirectApplication {
public static void main(String[] args) {
SpringApplication.run(LoginRedirectApplication.class, args);
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.loginredirect;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
class LoginRedirectMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginPageInterceptor());
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.loginredirect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
class LoginRedirectSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password(encoder().encode("user")).roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterAfter(new LoginPageFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/loginUser").permitAll()
.antMatchers("/user*").hasRole("USER")
.and().formLogin().loginPage("/loginUser").loginProcessingUrl("/user_login")
.failureUrl("/loginUser?error=loginError").defaultSuccessUrl("/userMainPage").permitAll()
.and().logout().logoutUrl("/user_logout").logoutSuccessUrl("/loginUser").deleteCookies("JSESSIONID")
.and().csrf().disable();
}
@Bean
public static PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}

View File

@ -0,0 +1,32 @@
package com.baeldung.loginredirect;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
class UsersController {
@GetMapping("/userMainPage")
public String getUserPage() {
return "userMainPage";
}
@GetMapping("/loginUser")
public String getUserLoginPage() {
if (isAuthenticated()) {
return "redirect:userMainPage";
}
return "loginUser";
}
private boolean isAuthenticated() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || AnonymousAuthenticationToken.class.isAssignableFrom(authentication.getClass())) {
return false;
}
return authentication.isAuthenticated();
}
}

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-5.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="{noop}user" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<security:http pattern="/**" use-expressions="true" auto-config="true">
<security:intercept-url pattern="/loginUser" access="permitAll"/>
<security:intercept-url pattern="/user*" access="hasRole('ROLE_USER')"/>
<security:form-login login-page="/loginUser"
login-processing-url="/user_login"
authentication-failure-url="/loginUser?error=loginError"
default-target-url="/userMainPage"/>
<security:csrf disabled="true"/>
<security:logout logout-url="/user_logout" delete-cookies="JSESSIONID" logout-success-url="/loginUser"/>
<security:custom-filter after="BASIC_AUTH_FILTER" ref="loginPageFilter"/>
</security:http>
<beans:bean id="loginPageFilter" class="com.baeldung.loginredirect.LoginPageFilter"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/loginUser"/>
<bean class="com.baeldung.loginredirect.LoginPageInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Baeldung Login Redirect</title>
</head>
<body>
Welcome user! <a th:href="@{/user_logout}" >Logout</a>
</body>
</html>