是否可以仅通过重定向允许访问页面?

Posted

技术标签:

【中文标题】是否可以仅通过重定向允许访问页面?【英文标题】: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而不是查询参数... 如果用户未登录,您可能希望将用户从注销页面重定向回登录页面。 【参考方案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>

它似乎完美无缺。

【讨论】:

以上是关于是否可以仅通过重定向允许访问页面?的主要内容,如果未能解决你的问题,请参考以下文章

在刷新重定向页面时丢失访问令牌

在子域允许访问一个页面,如果试图访问其他页面重定向到主域名

使用 JSF 2.0 实现重定向登录的正确方法是啥?

防止用户直接访问 django 中的重定向 URL

CORS:对预检请求的响应未通过访问控制检查:预检请求不允许重定向

jquery重定向按钮点击