【问题标题】:Is it possible to allow access to a page only through redirection?是否可以仅通过重定向允许访问页面?
【发布时间】:2018-10-21 21:41:15
【问题描述】:

我正在使用 Spring Boot 和 Thymeleaf 开发一个应用程序。

我的自定义登录页面中有以下 sn-p:

<p th:if="${param.logout}">Logged out successfully</p>

本段与以下安全配置相关联:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/", "*.css").permitAll()
            .antMatchers("/myendpoint").authenticated()
            .and()
            .formLogin().loginPage("/login").permitAll()
            .and()
            .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll();
}

所以在注销后用户会被重定向到/login?logout 并显示注销消息。

我的问题是,当用户通过简单地将http://myserver:8080/login?logout 写入浏览器来明确导航到/login?logout 时,也会显示此消息。

是否可以阻止用户直接访问/login?logout(从而仅在实际注销时才显示消息)?

【问题讨论】:

  • 使用非常短暂的cookie而不是查询参数...
  • 如果用户未登录,您可能希望将用户从注销页面重定向回登录页面。

标签: java spring spring-security thymeleaf


【解决方案1】:

试试这个。

像follow一样创建类

AppConstant

public class AppConstant 
{
    public static final String USER = "user";
}

实用程序

public class Util {
    public static boolean checkSessionExist(HttpServletRequest request)

    {
        HttpSession session = request.getSession();
        if(session.getAttribute(AppConstant.USER) == null)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}

登录方式

if(//Login credentials)
{
    session.setAttribute(AppConstant.USER, usermaster);
    //usermaster= it is object of your user master
}

页面重定向

    UserMaster  usermaster = (UserMaster) session.getAttribute(AppConstant.USER);
    if(!Util.checkSessionExist(request))
    {
        return "redirect:login";
    }
    else
    {
         //Your Pager
    }

对每个页面重定向功能使用此方法。

【讨论】:

    【解决方案2】:

    另一种可能是前锋:

    http
        .logout()
            .logoutSuccessHandler(
                (request, response, authentication) -> {
                    request.setAttribute("loggedOut");
                    request.getRequestDispatcher("/logged-out")
                           .forward(request, response);
                });
    
    // ...
    
    @Controller
    class LoggedOutController {
        @PostMapping("/logged-out")
        public String loggedOut() {
            return "login";
        }
    }
    

    /logged-out 在哪里呈现登录页面,只是使用请求属性而不是参数来显示适当的消息。

    【讨论】:

      【解决方案3】:

      经过一些研究,我想出了使用RedirectAttributesaddFlashAttribute() 在注销时将数据传递到我的登录页面。

      因此,我没有将 logout 设置为查询参数,而是从我的安全配置中删除了 Spring 的默认注销处理:

      http
          .authorizeRequests()
          .antMatchers("/", "*.css").permitAll()
          .antMatchers("/myendpoint").authenticated()
          .and()
          .formLogin().loginPage("/login").permitAll();
      

      并在我的控制器中创建了以下自定义注销端点:

      @PostMapping("/logout-user")
      public String logout(HttpServletRequest request, RedirectAttributes attrs) {
          new SecurityContextLogoutHandler().logout(request, null, null);
      
          // this attribute will be received in /login
          attrs.addFlashAttribute("logout", true);
      
          return "redirect:/login";
      }
      

      所以我将我的注销请求发送到此端点并检查/login 中的logout 属性,以便在适当时显示注销消息:

      <p th:if="${logout}">Logged out successfully</p>
      

      它似乎完美无缺。

      【讨论】:

        猜你喜欢
        • 2014-07-14
        • 2016-01-08
        • 2020-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        • 1970-01-01
        • 2015-03-21
        相关资源
        最近更新 更多