spring security 入门教程 自定义登录页面

昨天写了一些spring security的基本操作,今天来分享一下如何自定义自己的登录页面。

项目准备

基于昨天的项目,pom依赖不变,spring boot版本为2.1.7.RELEASE

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

开始

其实这块需求做起来没有多少工作量,但就是有一些spring security的机制可能大家不清楚就会一直被某些问题困扰。我们一个一个来解决一下。

实现自定义登录页面这个需求,我们需要做以下两件事情:

  • 实现一个登录页面
  • 配置spring security默认使用我们自己实现的登录页面

实现一个登陆页面

这里呢我就简单的写一个表单,大家根据自己的实际情况写自己的登录页面。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<!--这里action的地址先随意写一个,后面我们去配置-->
<form action="/demo-login" method="post">
    <input type="text" name="username" />
    <input type="password" name="password">
    <button type="submit">登录</button>
</form>
</body>
</html>

这个页面命名为demo-login.html,需要放在\src\main\resources\resources\这个路径下(注意有两个resources文件夹)。放在这个路径下呢,项目启动起来之后可以直接访问到我们的html文件,这是spring boot默认配置。如果你不想放在这个文件夹下呢,就改一下spring boot的配置,具体怎么改呢网上很多,我就不再过多赘述了。

配置spring security

我们配置spring security需要写一个类,继承WebSecurityConfigurerAdapter,然后根据自己的需求重写一些方法。我们自定义登录页面这个需求只需要重写void configure(HttpSecurity http)这个方法即可。我们来写一下配置。

//不写这个注解配置不生效
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.formLogin()
            .loginPage("/demo-login.html")
            .loginProcessingUrl("/demo-login");
    }
}

上面写的配置很简单,我们大概解释一下。
第一行,表示spring security使用form表单登录的方式(另外还有一种登录的方式是Basic登录)
第二行,表示spring security默认的登录页路径为/demo-login.html,就是我们上面写的html文件的名字
第三行,表示处理登录请求的接口为/demo-login,就是我们上面写的form表单action属性的值

写到这里我们启动一下项目试一下,看看是什么结果。

发现我们可以直接访问到接口,不需要登录。这是因为我们重写了void configure(HttpSecurity http)这个方法,覆盖了spring security默认的访问控制的配置。我们来自己写一下这些配置。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.formLogin()
            .loginPage("/demo-login.html")
            .loginProcessingUrl("/demo-login")
            .and()
            .authorizeRequests()
            .anyRequest().authenticated();
    }
}

新加入了三行配置。就像字面意思上表示的一样,这三行配置表示所有的请求都需要认证。现在我们再来启动项目,访问一下接口。

这时候发现浏览器提示了重定向的次数过多错误,这是为啥呢?我们来分析一下我们在浏览器地址栏里面输入我们接口地址按下回车之后都发生了啥。

访问/hello接口,因为我们刚才配置了所有请求都需要身份认证,现在我们没有登录那自然就要跳转到登录页登录,跳转/demo-login.html。可是/demo-login.html也需要身份认证啊,那就再次跳转/demo-login.html,这样重复往返就死循环下去了。

问题讲清楚之后,那解决方案就很明确了,把/demo-login.html/demo-login(form表单action属性的值)配置为不需要认证,放行。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.formLogin()
            .loginPage("/demo-login.html")
            .loginProcessingUrl("/demo-login")
            .and()
            .authorizeRequests()
            .antMatchers("/demo-login.html", "/demo-login").permitAll()
            .anyRequest().authenticated();
    }
}

加入一行配置,放行/demo-login.html/demo-login。现在我们重启项目看一下。

现在就正常的显示了我们的登录页面,我们输入正确的用户名和密码尝试登录一下。

发现我们点击登录之后又回到了登录页面。查看网络请求,看到刚才那个登陆请求返回了302状态码。查看Java的console之后也没有发现什么异常。我们尝试看一下debug日志,看看问题出在哪里。

改变spring boot的日志级别,添加配置logging.level.root=debug,重启项目,重试刚才的操作,查看一下console。

我们发现报错了,显示无效的csrf token。这是因为spring security默认开启了csrf防护,只要在请求中带上csrf token就可以了。这个token在返回登录页面的时候spring security已经帮我们准备好了,只是我们没有使用模板引擎,所以取到token比较困难,这里我们把csrf关闭吧,大家可以自己摸索一下如何取到这个token,带上就完事了。重写一下配置。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.formLogin()
            .loginPage("/demo-login.html")
            .loginProcessingUrl("/demo-login")
            .and()
            .authorizeRequests()
            .antMatchers("/demo-login.html", "/demo-login").permitAll()
            .anyRequest().authenticated()
            .and()
            .csrf().disable();
    }
}

配置写到这就真的全部写完了。我们现在重启项目就可以登录访问接口了。

结语

需求实现了,总体来说没有太多的代码量。但是过程中会遇到很多问题,需要大家耐心的去发现。里面涉及到的一些技巧,像查看debug日志,就需要大家静下心来慢慢的查看问题出在哪里。通过自己独立思考解决问题也很过瘾。

话不多说,拜拜。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容