欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

SpringBoot 高级教程 (81) Spring Security 自定义验证-v 重写表单登录页面

最编程 2024-10-13 19:54:26
...

默认的登录页面过于简陋,我们可以自己定义一个登录页面。为了方便起见,我们直接在src/main/resources/resources目录下定义一个login.html(不需要Controller跳转)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <link rel="stylesheet" href="css/login.css" type="text/css">
</head>
<body>
<form class="login-page" action="/login" method="post">
    <div class="form">
        <h3>请登录</h3>
        <input type="text" placeholder="请输入用户名" name="username" required="required" />
        <br/>
        <input type="password" placeholder="请输入密码" name="password" required="required" />
        <br/>
        <button type="submit">登录</button>
    </div>
</form>
</body>
</html>

要怎么做才能让Spring Security跳转到我们自己定义的登录页面呢?很简单,只需要在BrowserSecurityConfig的configure中添加一些配置:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin() // 表单登录
                .loginPage("/login.html")       // 登录跳转url
                .loginProcessingUrl("/login")   // 处理表单登录url
                .and()
                .authorizeRequests()            // 授权配置
                .antMatchers("/login.html", "/css/**").permitAll()  // 无需认证
                .anyRequest()                   // 所有请求
                .authenticated()                // 都需要认证
                .and().csrf().disable();
    }

在未登录的情况下,当用户访问html资源的时候跳转到登录页,否则返回JSON格式数据,状态码为401。要实现这个功能我们将loginPage的URL改为/authentication/require,并且在antMatchers方法中加入该URL,让其免拦截:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin() // 表单登录
 //             .loginPage("/login.html")       // 登录跳转url
                .loginPage("/authentication/require")
                .loginProcessingUrl("/login")   // 处理表单登录url
                .and()
                .authorizeRequests()            // 授权配置
                .antMatchers("/login.html", "/css/**", "/authentication/require").permitAll()  // 无需认证
                .anyRequest()                   // 所有请求
                .authenticated()                // 都需要认证
                .and().csrf().disable();
    }
添加controller
/**
 * @Author chen bo
 * @Date 2023/12
 * @Des
 */
@RestController
public class DemoController {
    private RequestCache requestCache = new HttpSessionRequestCache();
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @GetMapping("/authentication/require")
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public String requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        if (savedRequest != null) {
            String url = savedRequest.getRedirectUrl();
            // 为了方便测试,我们设置只有访问url中是以.html结尾时,才会跳转登录页,其它形式的全部返回提示语(访问资源需要身份认证)。具体业务中这里可以按需求设置。
            if (StringUtils.endsWithIgnoreCase(url, ".html")) {
                redirectStrategy.sendRedirect(request, response, "/login.html");
            }
        }

        return "访问资源需要身份认证";
    }
}

其中HttpSessionRequestCache为Spring Security提供的用于缓存请求的对象,通过调用它的getRequest方法可以获取到本次请求的HTTP信息。DefaultRedirectStrategy的sendRedirect为Spring Security提供的用于处理重定向的方法。

上面代码获取了引发跳转的请求,根据请求是否以.html为结尾来对应不同的处理方法。如果是以.html结尾,那么重定向到登录页面,否则返回”访问的资源需要身份认证!”信息,并且HTTP状态码为401(HttpStatus.UNAUTHORIZED)。

为了方便测试,添加hello.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
这是一个hello落地页
</body>
</html>

1.访问http://localhost:8080/hello的时候页面便会跳转到http://localhost:8080/authentication/require,并且输出”访问的资源需要身份认证!”

2.访问http://localhost:8090/hello.html的时候,页面将会跳转到登录页面。