Spring Security自定义表单登录详解

10 篇文章 0 订阅
5 篇文章 0 订阅

前面我们简单使用了 Spring Security Spring Security初使用
我们使用的是默认的登录页面,这个登录页面我们是可以自定义的。

接下来我们继续完善前面的 SecurityConfig 类,继续重写它的 configure(WebSecurity web) 和 configure(HttpSecurity http) 方法

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()//定义用户
                .withUser("zhangsan")//用户名
                .password("zhangsan123")//密码
                .roles("admin");//用户角色
        //如果需要配置多个用户,用 and 相连
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        //用来配置忽略掉的 URL 地址,一般对于静态文件,我们可以采用此操作。
        web.ignoring().antMatchers("/js/**", "/css/**", "/images/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()//结束当前标签,上下文回到HttpSecurity,开启新一轮的配置。
                .formLogin()
                .loginPage("/login.html")//登录页
                .permitAll()//登录相关的页面/接口不拦截。
                .and()
                .csrf().disable();//关闭csrf
    }
}

在resources下创建static,然后在static目录下创建登录页面login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>登录</title>
</head>
<body>
<div>
    <form action="/login.html" method="post">
        <div class="input">
            <label for="name">用户名</label>
            <input type="text" name="username" id="name">
        </div>
        <div class="input">
            <label for="pass">密码</label>
            <input type="password" name="password" id="pass">
        </div>
        <div class="button login">
            <button type="submit">登录</button>
        </div>
    </form>
</div>
</body>
</html>

这里没写样式,就简单演示一下
然后启动项目访问http://localhost:8080/hello,可以看到会重定向到http://localhost:8080/login.html
然后输入配置的用户名密码即可登录成功。

在 Spring Security 中,如果我们不做任何配置,默认的登录页面和登录接口的地址都是 /login,
GET 请求表示你想访问登录页面,如果是 POST 请求,表示你想提交登录数据。
当我们配置了 loginPage 为 /login.html 之后,就是设置登录页面和登录接口的地址为 /login.html。
如果想把登录页面和登录接口地址分开可以通过 loginProcessingUrl 方法来指定登录接口地址。

.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.permitAll()
.and()

然后修改login.html中form标签action值为/doLogin就可以登录成功。

form 表单的相关配置在 FormLoginConfigurer 中,该类继承自 AbstractAuthenticationFilterConfigurer,
在 AbstractAuthenticationFilterConfigurer 的构造方法中,有如下代码:
在这里插入图片描述
这里配置默认的 loginPage 为 /login
FormLoginConfigurer 的初始化方法 init 方法中也调用了父类的 init 方法:
在这里插入图片描述
而在父类的 init 方法中,又调用了 updateAuthenticationDefaults
在这里插入图片描述
可以看到,如果用户没有给 loginProcessingUrl 设置值的话,默认就使用 loginPage 作为 loginProcessingUrl。
所以这也是如果没配置两个配置地址是一样的原因。

登录表单中的参数是 username 和 password,我们可以回到 FormLoginConfigurer 类中,在它的构造方法中,我们可以看到有两个配置用户名密码的方法:
在这里插入图片描述
在这里,首先 super 调用了父类的构造方法,传入了 UsernamePasswordAuthenticationFilter 实例,该实例将被赋值给父类的 authFilter 属性。

接下来 usernameParameter 方法如下:
在这里插入图片描述
getAuthenticationFilter 实际上是父类的方法,在这个方法中返回了 authFilter 属性,也就是一开始设置的 UsernamePasswordAuthenticationFilter 实例,然后调用该实例的 setUsernameParameter 方法去设置登录用户名的参数:
在这里插入图片描述
当登录请求从浏览器来到服务端之后,我们要从请求的 HttpServletRequest 中取出来用户的登录用户名和登录密码,在 UsernamePasswordAuthenticationFilter 类中,有如下两个方法:
在这里插入图片描述
可以看到,这个时候,就用到默认配置的 username 和 password 了。

这两个参数我们也可以自己配置,配置方式如下:

.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.permitAll()
.and()

配置完成后,也要修改一下前端页面的name参数名,配置完成后,重启进行登录测试。

登录后我们要进行回调

登录成功回调

登录成功重定向 URL 相关的方法有两个:

  • defaultSuccessUrl
    如果我们在 defaultSuccessUrl 中指定登录成功的跳转页面为 /index,此时分两种情况,如果你是直接在浏览器中输入的登录地址,登录成功后,就直接跳转到 /index,如果你是在浏览器中输入了其他地址,例如 http://localhost:8080/hello,结果因为没有登录,又重定向到登录页面,此时登录成功后,就不会来到 /index ,而是来到 /hello 页面。
    defaultSuccessUrl 还有一个重载的方法,第二个参数如果不设置默认为 false,也就是我们上面的的情况,如果手动设置第二个参数为 true,则 defaultSuccessUrl 的效果和 successForwardUrl 一致。
  • successForwardUrl
    例如 successForwardUrl 指定的地址为 /index ,你在浏览器地址栏输入 http://localhost:8080/hello,结果因为没有登录,重定向到登录页面,当你登录成功之后,就会服务端跳转到 /index 页面;或者你直接就在浏览器输入了登录页面地址,登录成功后也是来到 /index。

相关配置如下:

.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.defaultSuccessUrl("/index")
.successForwardUrl("/index")
.permitAll()
.and()

「注意:实际操作中,defaultSuccessUrl 和 successForwardUrl 只需要配置一个即可。」

登录失败回调

与登录成功相似,登录失败也是有两个方法:

  • failureForwardUrl
  • failureUrl
    「这两个方法在设置的时候也是设置一个即可」
    failureForwardUrl 是登录失败之后会发生服务端跳转,failureUrl 则在登录失败之后,会发生重定向。
注销登录

注销登录的默认接口是 /logout

.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout","POST"))
.logoutSuccessUrl("/index")
.deleteCookies()
.clearAuthentication(true)
.invalidateHttpSession(true)
.permitAll()
.and()
  • 默认注销的 URL 是 /logout,是一个 GET 请求,我们可以通过 logoutUrl 方法来修改默认的注销 URL。
  • logoutRequestMatcher 方法不仅可以修改注销 URL,还可以修改请求方式,实际项目中,这个方法和 logoutUrl 任意设置一个即可。
  • logoutSuccessUrl 表示注销成功后要跳转的页面。
  • deleteCookies 用来清除 cookie。
  • clearAuthentication 和 invalidateHttpSession 分别表示清除认证信息和使 HttpSession 失效,默认可以不用配置,默认就会清除。

好了,这章到这里就结束了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security是一个在Java应用程序中提供身份验证和授权的框架。它通过使用各种身份验证和授权技术,帮助开发人员实现应用程序的安全性。 在Spring Security中,身份验证包括验证用户的身份以确保其是合法的,并且授权包括确定用户是否有权访问特定功能或资源。以下是Spring Security中的一些关键概念和用法: 1. 身份验证:Spring Security提供了许多身份验证机制,例如基于表单的身份验证、基于HTTP基本身份验证、基于LDAP的身份验证等。开发人员可以选择适合他们应用程序需求的身份验证机制。 2. 授权:Spring Security使用许可(Permission)和角色(Role)的概念来控制访问权限。可以使用特定的注解或编程方式将这些权限和角色应用到方法或URL上。 3. 认证和授权流程:Spring Security在认证和授权过程中使用了一系列的过滤器和提供者。它们分别负责处理身份验证和授权的不同方面。开发人员可以根据需要定制这些组件来满足自己的应用程序需求。 4. AccessDecisionManager:这是Spring Security中的一个重要组件,用于决定用户是否有权限访问特定的资源或功能。开发人员可以实现自己的AccessDecisionManager来根据自己的逻辑进行权限决策。 5. UserDetails:在Spring Security中,用户信息通过UserDetails接口进行封装。开发人员可以根据自己的需求实现自定义的UserDetails接口,并提供用户的身份验证和授权信息。 6. 匿名认证:Spring Security支持为匿名用户建立一个匿名Authentication对象。这样,无需再对匿名用户进行额外的验证,可以直接将其当作正常的Authentication对象来使用。 综上所述,Spring Security提供了全面的身份验证和授权机制来保护应用程序的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值