Return to the previous page after authorization, Spring Security AuthenticationSuccessHundler - spring

I have a login page (/page/login) and dropdown login forms in every page. I want user to be redirected to the page from which he has logged in (by dropdown login form), or the home page if it was from login page.
I tried to use AuthenticationSuccessHandler but it does not seems to work, every time it just redirects user to home page. What is the right way to solve it?
#Component
public class MySimpleUrlAuthenticationSuccessHendler implements AuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) throws IOException {
if(httpServletRequest.getContextPath().equals("/login")){
sendRedirect(httpServletRequest, httpServletResponse, "/user/profile");
}
else{
sendRedirect(httpServletRequest, httpServletResponse,httpServletRequest.getContextPath());
}
}
private void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException {
if(!response.isCommitted()){
new DefaultRedirectStrategy().sendRedirect(request,response,url);
}
}
}
Spring security config
package com.example.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
#Configuration
public class DemoSpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
AuthenticationSuccessHandler authenticationSuccessHandler;
#Autowired
UserDetailsService userDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.regexMatchers(HttpMethod.GET, "rating/place/[0-9]{0,}", "/place/[0-9]{0,}/liked/", "/rating/place/[0-9]{0,}")
.hasRole("USER")
.antMatchers(HttpMethod.GET, "/user/orders",
"/user/places")
.hasRole("USER")
.regexMatchers(HttpMethod.POST, "/menu/[0-9]{0,}/comment",
"/place/[0-9]{0,}/menu/[0-9]{0,}")
.hasRole("USER")
.regexMatchers(HttpMethod.POST, "/place/menu/[0-9]{0,}")
.hasRole("OWNER")
.antMatchers(HttpMethod.GET, "/newplace")
.authenticated()
.antMatchers(HttpMethod.POST, "/newplace")
.authenticated()
.antMatchers(HttpMethod.POST, "/registration")
.permitAll()
.antMatchers(HttpMethod.GET, "/resend", "/page/login", "/registration", "/place/")
.permitAll();
http
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/");
http
.rememberMe()
.key("rememberme");
http
.formLogin()
.loginPage("/page/login")
.failureUrl("/page/login")
.loginProcessingUrl("/login")
.usernameParameter("j_username")
.passwordParameter("j_password")
.successHandler(authenticationSuccessHandler);
http.
userDetailsService(userDetailsService);
http.
csrf().disable();
}
}

You need something like this in your AuthenticationSuccessHandler.

I also had similar requirement in my project and I solved this using below step:-
When the login form in dropdown is submitted I also send the current url (window.location.href) as a hidden request parameter.
Inside UserNamePasswordFilter and I get this parameter from request and store it in session (say variable name is redirectPrevUrl).
Now, in authentication success handler if this variable is present (i.e. redirectPrevUrl!=null) I redirect to this url instead of default home page.
This worked for me and I hope it will work for you as well,

Related

Spring security makes a session when a user access the log in page

I'm making log in page, following official guide.
I want to add a function which makes redirect to home if a user join.
The logic is like this.
A user join with email, password and username.
Joinpage redirect to log in page.
if there is authentication, directly go to home.
How can I redirect to home with authentication?
#Slf4j
#Controller
#RequiredArgsConstructor
public class LoginController {
#GetMapping("/login")
public String loginForm(#ModelAttribute LoginForm loginForm) {
return "login/loginForm";
}
}
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserSecurityService userSecurityService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 인가 요청 받기
.antMatchers("/", "/home", "/join",
"/css/**", "/*.ico", "/error").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.failureUrl("/login")
.usernameParameter("email")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true);
}
basically, the security generates user session along the SessionCreationPolicy value when the user logins successfully.
if you want to change the session system to stateless system.
but following the below code.
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}
and then, you need to set the authentication object.
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken("principal", "credentials", null));

How to prevent the user after logout when he enter the url in address bar he should get the login page

I have created a web application. Everything works fine.But, if the user is not logged in still they can have access to other jsp pages through url. I want to stop url access. I saw some example it shows the usage of filters. I'm new to filters I don't how to implement it. I'm using spring mvc
I think you want to use Spring security, you can check their official documentation
I think what you want is something that can be placed in your configuration class of WebSecurityConfigurerAdapter
In there, you can protect your pages from unauthenticated and unauthorized access by providing your implementation of configure(HttpSecurity http) method. This is the sample they provide on their documentation page:
package hello;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Bean
#Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}

Spring security always returning 403

Can someone tell me why this code is always returning 403?
I mapped /login to trigger the security login but it is not working properly.
package esercizio.security;
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;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("q#q").password("pluto").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").anonymous()
.antMatchers("/auth/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.jsp")
.defaultSuccessUrl("/auth/list-student")
.failureUrl("/errorPage")
.and()
.logout().logoutSuccessUrl("/login.jsp");
}
}
It should let anyone in if the URL doesn't start with /auth, I don't know why it doesn't happen.
I think, you must prepend 'ROLE_' to you authority like ROLE_USER.
For more visit :
Spring Security always return the 403 accessDeniedPage after login

Spring Security blocking Rest Controller

My app has Spring boot 1.3.2 and I'm trying use Spring MVC with Spring Security.
I have administration panel under http://localhost:8080/admin and my page content for common users under http://localhost:8080/
If You are trying to open an admin panel (http://localhost:8080/admin) You have to log in, if You are common just enter http://localhost:8080/ and have fun no log in required.
My Security config class:
import org.springframework.beans.factory.annotation.Autowired;
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;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password("password")
.roles("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/**").permitAll()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login");
}
}
Config above let me to require login from /admin
But I have some problem with Admin panel features.
This is Controller I'm trying to request with POST from admin panel:
#RestController
#RequestMapping("/admin/v1")
public class AdminController {
#RequestMapping(value = "/logout", method = RequestMethod.POST)
public String logout(HttpServletRequest request, HttpServletResponse response) {
String hello = "hi!";
return hello;
}
}
So I can log in, browser render Admin panel for me but when I'm clicking logout button which request POST logout method from Controller above. App tells me 403 Forbidden
Can anybody tell me what I'm doing wrong?
Most probably the 403 Forbidden error is because the spring by default enable csrf protection.
You can disable csrf in configuration or Include the CSRF Token in the POST method.
Disable csrf in config:
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/**").permitAll()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.and()
.logout()
.logoutSuccessUrl("/admin/v1/logout");
Include the CSRF Token in Form Submissions:
<c:url var="logoutUrl" value="/admin/v1/logout"/>
<form action="${logoutUrl}" method="post">
<input type="submit" value="Log out" />
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>

Allow Iframe for all domains while using Spring Security

I am using Spring Security. By default It doesn't allow a page to be loaded in iframe.
Spring Security set header X-Frame-Options value 'DENY'. I don't want this header to be include in my application.
Here is my configuration file.
package com.some.package.config;
import org.springframework.beans.factory.annotation.Autowired;
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.builders.WebSecurity;
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.util.matcher.AntPathRequestMatcher;
import com.some.package.crm.enums.Role;
import com.some.package.security.AuthSuccessHandler;
import com.some.package.security.AuthenticationProvider;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationProvider authenticationProvider;
#Autowired
private AuthSuccessHandler authSuccessHandler;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
#Bean
public PasswordEncoder getPasswordEncoder(){
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
#Override
public void configure(WebSecurity webSecurity) throws Exception
{
webSecurity
.ignoring()
// All of Spring Security will ignore the requests
.antMatchers("/resources/**", "/","/site/**","/affLinkCount", "/forgotPassword","/thirdPartyLogin", "/resetPassword", "/notifyCallbackToRecurring");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
/*
* Security Headers added by default
* Cache Control
* Content Type Options
* HTTP Strict Transport Security
* X-Frame-Options
* X-XSS-Protection
* csrf added by default
*/
http
.authorizeRequests()
.antMatchers("/crm/**").hasRole(Role.CUSTOMER.name())
.antMatchers("/analyst/**").hasRole(Role.ANALYST.name())
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?failed=true")
.successHandler(authSuccessHandler)
.usernameParameter("username")
.passwordParameter("password").loginProcessingUrl("/j_spring_security_check")
.permitAll()
.and()
.sessionManagement().sessionFixation().newSession()
.sessionAuthenticationErrorUrl("/login")
.invalidSessionUrl("/login")
.maximumSessions(1)
.expiredUrl("/login").and()
.and()
.exceptionHandling().accessDeniedPage("/login")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login")
.permitAll();
// .and().headers().frameOptions().disable();
// addFilterAfter(new IFrameEnableFilter(), HeaderWriterFilter.class);
//.headers().frameOptions().addHeaderWriter(new XFrameOptionsHeaderWriter(new WhiteListedAllowFromStrategy(Arrays.asList("localhost"))));
// .headers().addHeaderWriter(new XFrameOptionsHeaderWriter(new WhiteListedAllowFromStrategy(Arrays.asList("localhost"))));
}
}
If you are using Spring Security 4, then you can do this with something like:
http
.headers()
.frameOptions().disable()
.and()
// ...
You can find additional details in the 4.0.x reference.
In Spring Security 3.2.x things are a little different if you want to continue using the other HTTP headers. You need to do something like this:
http
.headers()
.contentTypeOptions();
.xssProtection()
.cacheControl()
.httpStrictTransportSecurity()
.frameOptions()
.and()
// ...
Additional details can be found in the 3.2.x reference.
Thank you #Rob Winch to your answer which leaded me to find a simple solution from the same source, where I could disable it in the xml configuration file as below:
<security:frame-options disabled="true"/>
I just shared this since it may be used by others in order to not do code changes, so it only requires configuration updates

Resources