如何使用 Spring Security 将登录的用户重定向到他的首页,将未登录的用户重定向到不同的用户

Posted

技术标签:

【中文标题】如何使用 Spring Security 将登录的用户重定向到他的首页,将未登录的用户重定向到不同的用户【英文标题】:How to redirect, with Spring Security, a logged user to his front page and a non logged one to a different one 【发布时间】:2019-10-08 19:30:31 【问题描述】:

我正在做一个 Spring Web 应用程序项目作为学校的期末项目。我们使用带有 Hibernate 和 H2 数据库的 SpringBoot。为了进行身份验证和授权,我们使用 Spring Security。我们还将模型 View-Controller 与存储库、服务和控制器一起使用。 我有一个初始首页(with the URL "/"),在您打开项目时显示。登录后,您将被重定向到另一个带有 URL ("/portadaUsuario") 的首页(我来自西班牙,所以有很多西班牙语名称)。但是,如果您在登录后以某种方式结束了 ("/") URL,您将看到与未登录用户显示的相同首页,其中包含注册和登录选项,其中显然是错误的。

我知道我可以使用 spring 安全标签和元素显示不同的 html 元素,但是我已经围绕两个不同的首页构建了我的项目,如果可能的话,我希望保持这种方式。如果无法实现,请告诉我应该如何在同一个 HTML 文件中显示不同的元素。

这是我的 WellcomeController 的方法

@Controller
public class PortadaController 

    @GetMapping("/")
    public String mostrarPortada() 
        return "portada";
    

    @GetMapping("/portadaUser")
    public String mostrarPortadaUsuario() 
        return "/usuario/portada";
    

以下是对用户进行身份验证的方法

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .authorizeRequests()
                .antMatchers("/css/**","/js/**","/webjars/**", "/h2-console/**", "/", "/newUser/**").permitAll()
                        .antMatchers("/admin/**").hasAnyRole("ADMIN")
                        .anyRequest().authenticated()
                        .and()
                .formLogin()
                        .loginPage("/login")
                        .permitAll()
                        .successHandler(customSuccessHandler)
                        .defaultSuccessUrl("/portadaUser")
                        .and()
                .logout()
                        .logoutUrl("/logout")
                        .permitAll()
                        .logoutSuccessUrl("/")
                        .and()
                .exceptionHandling()
                        .accessDeniedPage("/acceso-denegado");


        http.csrf().disable();
        http.headers().frameOptions().disable();
        

我想要的是应用程序检测登录用户何时请求“/” URL,并将其重定向到 /portadaUser

【问题讨论】:

【参考方案1】:

在 jsp + Spring 4.3.13 + Spring Security 4.2.11 中测试

1.签入jsp

""

<script>
    <sec:authorize access="hasRole('ADMIN')">
        location.replace('/yourpage')
    </sec:authorize>
</script>  

2。签入控制器SpringSecurityUtil.class

 public class SpringSecurityUtil 

        public static boolean hasRole(String role) 
            Collection<GrantedAuthority> authorities = (Collection<GrantedAuthority>) SecurityContextHolder.getContext().getAuthentication().getAuthorities();
            boolean hasRole = false;
            for (GrantedAuthority authority : authorities) 
                if(authority.getAuthority().equals(role)) 
                    hasRole = true;
                    break;
                
            

            return hasRole;
        

    

HomeController.class

@Controller
public class HomeController 

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(HttpServletResponse resp) 
        if(SpringSecurityUtil.hasRole("ADMIN"))
            //if has role send your page
        else
            //if has not role send your page
    
  

3。在 Spring Security Config 类中添加 antMatchers。

antMatchers("/").hasAnyRole("ADMIN")

4。使用@PreAuthority

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 
    ...

HomeController.class

 @Controller
    public class HomeController 

        @PreAuthorize("hasAuthority('ADMIN')")
        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String home() 
              //If this code starts, you have ADMIN privileges.
        
      

查看更多Spring Security Method Security

【讨论】:

【参考方案2】:

假设您有两个页面,一个用于登录(已登录),另一个用于未登录(未登录-home),您编写如下代码 -

@GetMapping("/")
public String index(Principal principal, Model model) 
   return principal != null ? "signed-in-home" : "not-signed-in-home";

在这里阅读更多关于校长的信息-https://www.baeldung.com/get-user-in-spring-security

【讨论】:

以上是关于如何使用 Spring Security 将登录的用户重定向到他的首页,将未登录的用户重定向到不同的用户的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Security 成功登录后如何正确更新登录日期时间?

如何使用 Spring Security 登录页面传递附加参数

使用 Spring Security 成功登录后如何将用户转发回所需的受保护页面

如何使用 Spring Security + Angular 登录/验证

如何使用 Spring Security 和 Thymeleaf 获取当前登录用户的 ID

spring security 重定向登录时端口 8080 来自哪里?如何将其更改为使用端口 443?