表单
自定义表单登陆页
- java配置
@EnableWebSecurity
public class SecurityConfig2 extends WebSecurityConfigurerAdapter {
/**
* authorizeRequests() 意思就是开始配置请求校验
* anyRequest() 匹配所有的请求
* authenticated() 表示所匹配的URL都需要被认证才能访问
* loginPage() 自定义表单登陆页面
* @param http
* @throws Exception
*/
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().anyRequest().
authenticated().and()
.formLogin().
loginPage("/myLogin.html").
permitAll().and().csrf().disable();
}
}
- html模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<form action="myLogin.html" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2">
<button type="submit">登录</button>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
<style>
div{
width: 400px;
height: 400px;
margin: 0 auto;
}
</style>
- 疑惑
- 为啥html里的action与loginpage(),要配置成一样呢?
源码默认登陆页为login
protected AbstractAuthenticationFilterConfigurer() {
this.defaultSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler();
this.successHandler = this.defaultSuccessHandler;
this.setLoginPage("/login");
}
FormLoginConfigurer的init方法调用了父类的init方法
public void init(H http) throws Exception {
super.init(http);
this.initDefaultLoginFilter(http);
}
父类 AbstractAuthenticationFilterConfigurer的init方法调用了this.updateAuthenticationDefaults(),如果loginProcessingUrl == null则使用loginpage
public void init(B http) throws Exception {
this.updateAuthenticationDefaults();
this.updateAccessDefaults(http);
this.registerDefaultAuthenticationEntryPoint(http);
}
protected final void updateAuthenticationDefaults() {
if (this.loginProcessingUrl == null) {
this.loginProcessingUrl(this.loginPage);
}
if (this.failureHandler == null) {
this.failureUrl(this.loginPage + "?error");
}
LogoutConfigurer<B> logoutConfigurer = (LogoutConfigurer)((HttpSecurityBuilder)this.getBuilder()).getConfigurer(LogoutConfigurer.class);
if (logoutConfigurer != null && !logoutConfigurer.isCustomLogoutSuccess()) {
logoutConfigurer.logoutSuccessUrl(this.loginPage + "?logout");
}
}
同理一样的继续追寻设置loginPage方法,FormLoginConfigurer的loginPage调用了父类的loginPage,
父类的loginPage调用了this.updateAuthenticationDefaults()
public FormLoginConfigurer<H> loginPage(String loginPage) {
return (FormLoginConfigurer)super.loginPage(loginPage);
}
protected T loginPage(String loginPage) {
this.setLoginPage(loginPage);
this.updateAuthenticationDefaults();
this.customLoginPage = true;
return this.getSelf();
}
从上可知我们开始自定义登陆接口代码如下,前端action改为login
@EnableWebSecurity
public class SecurityConfig2 extends WebSecurityConfigurerAdapter {
/**
* authorizeRequests() 意思就是开始配置请求校验
* anyRequest() 匹配所有的请求
* authenticated() 表示所匹配的URL都需要被认证才能访问
* loginPage() 自定义表单登陆页面
* loginProcessingUrl() 自定义登陆接口
* @param http
* @throws Exception
*/
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().anyRequest().
authenticated().and()
.formLogin().
loginPage("/myLogin.html").loginProcessingUrl("/login").
permitAll().and().csrf().disable();
}
}
<form action="login" method="post">
.....
- 自定义登陆参数
FormLoginConfigurer.class默认配置
public FormLoginConfigurer() {
super(new UsernamePasswordAuthenticationFilter(), (String)null);
this.usernameParameter("username");
this.passwordParameter("password");
}
code如下
/**
* authorizeRequests() 意思就是开始配置请求校验
* anyRequest() 匹配所有的请求
* authenticated() 表示所匹配的URL都需要被认证才能访问
* loginPage() 自定义表单登陆页面
* loginProcessingUrl() 自定义登陆接口
* usernameParameter() 自定义用户名
* passwordParameter() 自定义密码
*
* @param http
* @throws Exception
*/
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().anyRequest().
authenticated().and()
.formLogin().
loginPage("/myLogin.html").loginProcessingUrl("/login").
usernameParameter("uname").passwordParameter("pwd").
permitAll().and().csrf().disable();
}
<tr>
<td>用户名:</td>
<td><input type="text" name="uname"/></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="pwd"/></td>
</tr>
- 其它
- successForwardUrl 表示登陆成功之后跳转的页面,不管你之前的请求地址是啥
- failureForwardUrl 登陆失败跳转的页面
- defaultSuccessUrl 如果访问的地址是 hello,则登陆成功之后跳转到hello,不会跳转到index,默认为false,它有两个方法,如果设置为true则与successForwardUrl 效果一样
- 相关code如下
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().anyRequest().
authenticated().and()
.formLogin().
loginPage("/myLogin.html").loginProcessingUrl("/login").
usernameParameter("uname").passwordParameter("pwd").defaultSuccessUrl("/index")
.successForwardUrl("/index").failureForwardUrl("/error").
permitAll().and().csrf().disable();
}
public final T defaultSuccessUrl(String defaultSuccessUrl) {
return this.defaultSuccessUrl(defaultSuccessUrl, false);
}
public final T defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse) {
SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.setDefaultTargetUrl(defaultSuccessUrl);
handler.setAlwaysUseDefaultTargetUrl(alwaysUse);
this.defaultSuccessHandler = handler;
return this.successHandler(handler);
}
protected final void updateAuthenticationDefaults() {
if (this.loginProcessingUrl == null) {
this.loginProcessingUrl(this.loginPage);
}
//不配置在loginPage 后面追加?error
if (this.failureHandler == null) {
this.failureUrl(this.loginPage + "?error");
}
LogoutConfigurer<B> logoutConfigurer = (LogoutConfigurer)((HttpSecurityBuilder)this.getBuilder()).getConfigurer(LogoutConfigurer.class);
if (logoutConfigurer != null && !logoutConfigurer.isCustomLogoutSuccess()) {
logoutConfigurer.logoutSuccessUrl(this.loginPage + "?logout");
}
}
//初始化配置
private void init(UsernamePasswordAuthenticationFilter authFilter, AbstractAuthenticationProcessingFilter openIDFilter) {
this.loginPageUrl = "/login";
this.logoutSuccessUrl = "/login?logout";
this.failureUrl = "/login?error";
if (authFilter != null) {
this.formLoginEnabled = true;
this.usernameParameter = authFilter.getUsernameParameter();
this.passwordParameter = authFilter.getPasswordParameter();
if (authFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
this.rememberMeParameter = ((AbstractRememberMeServices)authFilter.getRememberMeServices()).getParameter();
}
}
if (openIDFilter != null) {
this.openIdEnabled = true;
this.openIDusernameParameter = "openid_identifier";
if (openIDFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
this.openIDrememberMeParameter = ((AbstractRememberMeServices)openIDFilter.getRememberMeServices()).getParameter();
}
}
}