spring-security Spring Security -成功登录后重定向到输入的url

blpfk2vs  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(250)

我一直在Spring Security上工作,我使用基于角色的身份验证。如果用户是admin,他将被定向到admindashboard,用户将被重定向到他各自的 Jmeter 板,在那里他们共享一个公共的登录门户。
如果一个人在登录前输入了管理员/用户 Jmeter 板的URL,它会要求该人登录,但不会重定向到输入的URL。相反,会抛出错误“无法调用sendRedirect”。
我的安全配置文件代码

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.web.util.UrlPathHelper;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired private LoginSuccessHandler loginSuccessHandler;
    @Bean
    AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider=new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(new BCryptPasswordEncoder());
        return provider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/").permitAll()
        .antMatchers("/userhome").hasAuthority("USER").
        antMatchers("/adminhome").hasAuthority("ADMIN")
        .antMatchers("/register").permitAll()
        .and().formLogin().loginPage("/login")
        .successHandler(loginSuccessHandler)
        .permitAll().and().logout().logoutSuccessHandler(new LogoutSuccessHandler() {
            @Override
            public void onLogoutSuccess(HttpServletRequest request,HttpServletResponse response,Authentication authentication) throws   IOException,ServletException{
                System.out.println("The User "+authentication.getName() + " has logged out");
                UrlPathHelper helper=new UrlPathHelper();
                String context=helper.getContextPath(request);
                response.sendRedirect(context+"/home");
            }
        }).permitAll();
        http.csrf().disable();

    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

我的登录成功处理程序

package strictly.cinema.config;

import java.io.IOException;
import java.util.Collection;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import strictly.cinema.service.CustomUserDetails;

@Component
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
    @Override
     public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                Authentication authentication) throws ServletException, IOException {

            CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
            Collection<? extends GrantedAuthority> authorities =userDetails.getAuthorities();
            authorities.forEach(auth->System.out.println(auth.getAuthority()));
            String redirectURL=request.getContextPath();
            if(userDetails.hasRole("USER"))
                redirectURL+="/userhome";
            else if(userDetails.hasRole("ADMIN"))
                redirectURL+="/adminhome";

            response.sendRedirect(redirectURL);
            super.onAuthenticationSuccess(request, response, authentication); 
        }
}

覆盖安全处理程序本身中的注销处理程序。需要帮助来存储输入的URL。一旦用户通过身份验证并有资格访问该URL,则应在登录后将其重定向到该URL

cpjpxq1n

cpjpxq1n1#

您可以不使用successHandler,而是将其重定向到一个成功端点,如下所示:

.defaultSuccessUrl("/loginSuccess")

新端点会根据他的角色将他重定向到“/userhome”或“/adminhome”。(以下未进行测试)
成功终点:

@GetMapping("/loginSuccess")
public void getLoginInfo(
        @AuthenticationPrincipal UserDetails authentication,
        HttpServletResponse response) throws IOException {
    if (authentication.getAuthorities()
            .contains(new SimpleGrantedAuthority("ADMIN"))) {
        response.sendRedirect("/adminhome");
    } else {
        response.sendRedirect("/userhome");
    }
}

相关问题