前几篇文章中我们提到了如何自定义Spring Security默认登录界面的用户名和密码,总结下来提到了两种方式:
Spring Security默认登录界面挺好看的,但是可不可以自定义?肯定是可以的,下面进行演示。
login.html代码如下:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login Pagetitle>
head>
<body>
<h2>Loginh2>
<form action="/login" method="post">
Username: <input type="text" name="username"/><br/>
Password: <input type="password" name="password"/><br/>
<input type="submit" value="Login"/>
form>
body>
html>
其他文件的代码不需要改变,只需要在SecurityConfig中写入一些配置,即可自定义界面,SecurityConfig中代码如下:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 在该方法中对登录页面进行自定义
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); // 关闭跨域攻击
http.formLogin() // 配置登录表单使用哪个页面
.loginPage("/login.html") // 指定登录页面为login.html
.loginProcessingUrl("/login") // 指定处理登录请求的路径
.defaultSuccessUrl("/index.html"); // 指定登录成功后跳转的路径
http.authorizeRequests() // 放行一些资源
.antMatchers("/login.html") // 这里写你要放行的资源
.permitAll() // 在这个方法之上的资源(如login.html)都允许直接访问
.anyRequest().authenticated(); // 除了以上资源,其他资源必须认证才可访问
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
必要解释:
指定了登录页面为login.html后,需要放行(即不登录也可以访问)该html文件资源,这样才可以在登录时访问到。因为对于Spring Security来说,login.html和index.html等文件都是服务器的资源,需要认证(即登录)后才能访问。
OK,启动项目,打开浏览器,访问http://localhost:8080
,可以看到我们自定义的用户界面:
输入用户名:admin
和密码:1234
。若看到如下页面,则说明登录成功:
1)访问http://localhost:8080
打开Chrome的开发者工具,重新启动项目,访问http://localhost:8080
,在Network中可以看到,总共发送了两个请求:
localhost
是浏览器发送的第一个请求,如下:
可以看到该请求的响应码是302,即重定向。响应报文里提供了让浏览器访问哪个路径,即Location头中的信息:
因此,浏览器会往这个地址发送一个请求,即请求login.html资源。
在输入用户名和密码,点击登录后,也会发送两个请求:
login
是浏览器发送的第一个请求,如下:
状态码是302,即重定向(具体来说是,该资源原本确实存在于这个路径,但已经临时改变了位置)。该请求的响应报文中,Location头中的信息为http://localhost:8080/
,即让浏览器访问这个路径。
localhost
是浏览器发送的第二个请求,如下:
这说明,我们点击登录后,发生了重定向。
引用这篇博客中的例子:
用生活中一个常见的例子来说明两者之间的区别,某人要去办理护照:
请求转发:小明去了甲局,甲局看了之后,知道护照应该由乙局来管,让小明等着,由甲局把护照交给乙局,乙局办好后送到了甲局,然后甲局的工作人员将护照交给了某人;
重定向:小明去了甲局后,甲局的工作人员说护照不归他们关,应该去乙局。然后小明就去乙局办护照。
仔细阅读我们这个例子的login.html中的代码:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login Pagetitle>
head>
<body>
<h2>Loginh2>
<form action="/login" method="post">
Username: <input type="text" name="username"/><br/>
Password: <input type="password" name="password"/><br/>
<input type="submit" value="Login"/>
form>
body>
html>
在登录页面,我们需要用户输入一些信息,那么一般会采用表单的方式来收集这些信息。
那么在这个login.html中,我们定义了一个表单,指定了form标签的两个属性:
action="/login"
:该表单会提交到/login
这个urlmethod="post"
:表单提交时的请求方法为POST注意,对应用户名和密码的input标签的name属性要分别为username
和password
,只字不能差。Spring Security默认会将name属性为username的input标签中的信息读取为用户名,会将name属性为password的input标签中的信息读取为密码。
那么我们是否可以对这些input标签中的name属性进行自定义呢?比如我想要像下面这么写:
Username: <input type="text" name="user"/><br/>
Password: <input type="password" name="pwd"/><br/>
答案是可以的。可以在SecurityConfig中进行配置。
http.formLogin() // 配置登录表单使用哪个页面
.loginPage("/login.html") // 指定登录页面为login.html
.loginProcessingUrl("/login") // 指定处理登录请求的路径
.defaultSuccessUrl("/index.html") // 指定登录成功后跳转的路径
.usernameParameter("user")
.passwordParameter("pwd");
在usernameParameter()
和passwordParameter()
中进行自定义。
在登录成功后,可以使用登录成功处理器来执行一些业务逻辑: