一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Boot整合Spring Security簡單實現登入登出從零搭建教程

Spring Boot整合Spring Security簡單實現登入登出從零搭建教程

2021-05-31 11:20EalenXie Java教程

這篇文章主要給大家介紹了關于Spring Boot整合Spring Security簡單實現登入登出從零搭建的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧

前言

spring security是一個能夠為基于spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在spring應用上下文中配置的bean,充分利用了spring ioc,di(控制反轉inversion of control ,di:dependency injection 依賴注入)和aop(面向切面編程)功能,為應用系統提供聲明式的安全訪問控制功能,減少了為企業系統安全控制編寫大量重復代碼的工作。

本文主要給大家介紹了關于spring boot整合spring security實現登入登出的相關內容,下面話不多說了,來一起看看詳細的介紹吧

技術棧 : springboot + springsecurity + jpa + freemark ,完整項目地址 : https://github.com/ealenxie/spring-security-login

方法如下:

1 . 新建一個spring-security-login的maven項目 ,pom.xml添加基本依賴 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
 xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelversion>4.0.0</modelversion>
 
 <groupid>com.wuxicloud</groupid>
 <artifactid>spring-security-login</artifactid>
 <version>1.0</version>
 <parent>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-parent</artifactid>
 <version>1.5.6.release</version>
 </parent>
 <properties>
 <author>ealenxie</author>
 <description>springboot整合springsecurity實現簡單登入登出</description>
 </properties>
 
 <dependencies>
 <dependency>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter</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-data-jpa</artifactid>
 </dependency>
 <dependency>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-test</artifactid>
 </dependency>
 <dependency>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-security</artifactid>
 </dependency>
 <dependency>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-freemarker</artifactid>
 </dependency>
 <dependency>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-aop</artifactid>
 </dependency>
 <!--alibaba-->
 <dependency>
 <groupid>com.alibaba</groupid>
 <artifactid>druid</artifactid>
 <version>1.0.24</version>
 </dependency>
 <dependency>
 <groupid>com.alibaba</groupid>
 <artifactid>fastjson</artifactid>
 <version>1.2.31</version>
 </dependency>
 <dependency>
 <groupid>mysql</groupid>
 <artifactid>mysql-connector-java</artifactid>
 <scope>runtime</scope>
 </dependency>
 </dependencies>
</project>

2 . 準備你的數據庫,設計表結構,要用戶使用登入登出,新建用戶表。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
drop table if exists `user`;
create table `user` (
 `id` int(11) not null auto_increment,
 `user_uuid` varchar(70) character set utf8 collate utf8_general_ci default null,
 `username` varchar(255) character set utf8 collate utf8_general_ci default null,
 `password` varchar(255) character set utf8 collate utf8_general_ci default null,
 `email` varchar(255) character set utf8 collate utf8_general_ci default null,
 `telephone` varchar(255) character set utf8 collate utf8_general_ci default null,
 `role` int(10) default null,
 `image` varchar(255) character set utf8 collate utf8_general_ci default null,
 `last_ip` varchar(255) character set utf8 collate utf8_general_ci default null,
 `last_time` varchar(255) character set utf8 collate utf8_general_ci default null,
 primary key (`id`) using btree
) engine = innodb auto_increment = 2 character set = utf8 collate = utf8_general_ci row_format = compact;
 
set foreign_key_checks = 1;

3 . 用戶對象user.java :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import javax.persistence.*;
 
/**
 * created by ealenxie on 2018/7/5 15:17
 */
@entity
@table(name = "user")
public class user {
 @id
 @generatedvalue(strategy = generationtype.auto)
 private integer id;
 private string user_uuid; //用戶uuid
 private string username; //用戶名
 private string password; //用戶密碼
 private string email; //用戶郵箱
 private string telephone; //電話號碼
 private string role; //用戶角色
 private string image; //用戶頭像
 private string last_ip; //上次登錄ip
 private string last_time; //上次登錄時間
 
 public integer getid() {
 return id;
 }
 
 public string getrole() {
 return role;
 }
 
 public void setrole(string role) {
 this.role = role;
 }
 
 public string getimage() {
 return image;
 }
 
 public void setimage(string image) {
 this.image = image;
 }
 
 public void setid(integer id) {
 this.id = id;
 }
 
 
 public string getusername() {
 return username;
 }
 
 public void setusername(string username) {
 this.username = username;
 }
 
 public string getemail() {
 return email;
 }
 
 public void setemail(string email) {
 this.email = email;
 }
 
 public string gettelephone() {
 return telephone;
 }
 
 public void settelephone(string telephone) {
 this.telephone = telephone;
 }
 
 public string getpassword() {
 return password;
 }
 
 public void setpassword(string password) {
 this.password = password;
 }
 
 public string getuser_uuid() {
 return user_uuid;
 }
 
 public void setuser_uuid(string user_uuid) {
 this.user_uuid = user_uuid;
 }
 
 public string getlast_ip() {
 return last_ip;
 }
 
 public void setlast_ip(string last_ip) {
 this.last_ip = last_ip;
 }
 
 public string getlast_time() {
 return last_time;
 }
 
 public void setlast_time(string last_time) {
 this.last_time = last_time;
 }
 
 @override
 public string tostring() {
 return "user{" +
 "id=" + id +
 ", user_uuid='" + user_uuid + '\'' +
 ", username='" + username + '\'' +
 ", password='" + password + '\'' +
 ", email='" + email + '\'' +
 ", telephone='" + telephone + '\'' +
 ", role='" + role + '\'' +
 ", image='" + image + '\'' +
 ", last_ip='" + last_ip + '\'' +
 ", last_time='" + last_time + '\'' +
 '}';
 }
}

 4 . application.yml配置一些基本屬性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
spring:
 resources:
 static-locations: classpath:/
 freemarker:
 template-loader-path: classpath:/templates/
 suffix: .html
 content-type: text/html
 charset: utf-8
 datasource:
 url: jdbc:mysql://localhost:3306/yourdatabase
 username: yourname
 password: yourpass
 driver-class-name: com.mysql.jdbc.driver
 type: com.alibaba.druid.pool.druiddatasource
server:
 port: 8083
 error:
 whitelabel:
 enabled: true

5 . 考慮我們應用的效率 , 可以配置數據源和線程池 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.wuxicloud.config;
 
import com.alibaba.druid.pool.druiddatasource;
import com.alibaba.druid.pool.druiddatasourcefactory;
import com.alibaba.druid.support.http.statviewservlet;
import com.alibaba.druid.support.http.webstatfilter;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.boot.context.properties.configurationproperties;
import org.springframework.boot.web.servlet.filterregistrationbean;
import org.springframework.boot.web.servlet.servletregistrationbean;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.core.env.*;
 
import javax.sql.datasource;
import java.util.hashmap;
import java.util.map;
import java.util.properties;
 
@configuration
public class druidconfig {
 private static final string db_prefix = "spring.datasource.";
 
 @autowired
 private environment environment;
 
 @bean
 @configurationproperties(prefix = db_prefix)
 public datasource druiddatasource() {
 properties dbproperties = new properties();
 map<string, object> map = new hashmap<>();
 for (propertysource<?> propertysource : ((abstractenvironment) environment).getpropertysources()) {
 getpropertiesfromsource(propertysource, map);
 }
 dbproperties.putall(map);
 druiddatasource dds;
 try {
 dds = (druiddatasource) druiddatasourcefactory.createdatasource(dbproperties);
 dds.init();
 } catch (exception e) {
 throw new runtimeexception("load datasource error, dbproperties is :" + dbproperties, e);
 }
 return dds;
 }
 
 private void getpropertiesfromsource(propertysource<?> propertysource, map<string, object> map) {
 if (propertysource instanceof mappropertysource) {
 for (string key : ((mappropertysource) propertysource).getpropertynames()) {
 if (key.startswith(db_prefix))
  map.put(key.replacefirst(db_prefix, ""), propertysource.getproperty(key));
 else if (key.startswith(db_prefix))
  map.put(key.replacefirst(db_prefix, ""), propertysource.getproperty(key));
 }
 }
 
 if (propertysource instanceof compositepropertysource) {
 for (propertysource<?> s : ((compositepropertysource) propertysource).getpropertysources()) {
 getpropertiesfromsource(s, map);
 }
 }
 }
 
 @bean
 public servletregistrationbean druidservlet() {
 return new servletregistrationbean(new statviewservlet(), "/druid/*");
 }
 
 @bean
 public filterregistrationbean filterregistrationbean() {
 filterregistrationbean filterregistrationbean = new filterregistrationbean();
 filterregistrationbean.setfilter(new webstatfilter());
 filterregistrationbean.addurlpatterns("/*");
 filterregistrationbean.addinitparameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
 return filterregistrationbean;
 }
}

配置線程池 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.wuxicloud.config;
 
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.scheduling.annotation.enableasync;
import org.springframework.scheduling.concurrent.threadpooltaskexecutor;
 
import java.util.concurrent.executor;
import java.util.concurrent.threadpoolexecutor;
 
@configuration
@enableasync
public class threadpoolconfig {
 @bean
 public executor getexecutor() {
 threadpooltaskexecutor executor = new threadpooltaskexecutor();
 executor.setcorepoolsize(5);//線程池維護線程的最少數量
 executor.setmaxpoolsize(30);//線程池維護線程的最大數量
 executor.setqueuecapacity(8); //緩存隊列
 executor.setrejectedexecutionhandler(new threadpoolexecutor.callerrunspolicy()); //對拒絕task的處理策略
 executor.setkeepaliveseconds(60);//允許的空閑時間
 executor.initialize();
 return executor;
 }
}

6.用戶需要根據用戶名進行登錄,訪問數據庫 :

?
1
2
3
4
5
6
7
8
9
10
11
import com.wuxicloud.model.user;
import org.springframework.data.jpa.repository.jparepository;
 
/**
 * created by ealenxie on 2018/7/11 14:23
 */
public interface userrepository extends jparepository<user, integer> {
 
 user findbyusername(string username);
 
}

7.構建真正用于springsecurity登錄的安全用戶(userdetails),我這里使用新建了一個pojo來實現 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.wuxicloud.security;
 
import com.wuxicloud.model.user;
import org.springframework.security.core.grantedauthority;
import org.springframework.security.core.authority.simplegrantedauthority;
import org.springframework.security.core.userdetails.userdetails;
 
import java.util.arraylist;
import java.util.collection;
 
public class securityuser extends user implements userdetails {
 private static final long serialversionuid = 1l;
 
 public securityuser(user user) {
 if (user != null) {
 this.setuser_uuid(user.getuser_uuid());
 this.setusername(user.getusername());
 this.setpassword(user.getpassword());
 this.setemail(user.getemail());
 this.settelephone(user.gettelephone());
 this.setrole(user.getrole());
 this.setimage(user.getimage());
 this.setlast_ip(user.getlast_ip());
 this.setlast_time(user.getlast_time());
 }
 }
 
 @override
 public collection<? extends grantedauthority> getauthorities() {
 collection<grantedauthority> authorities = new arraylist<>();
 string username = this.getusername();
 if (username != null) {
 simplegrantedauthority authority = new simplegrantedauthority(username);
 authorities.add(authority);
 }
 return authorities;
 }
 
 @override
 public boolean isaccountnonexpired() {
 return true;
 }
 
 @override
 public boolean isaccountnonlocked() {
 return true;
 }
 
 @override
 public boolean iscredentialsnonexpired() {
 return true;
 }
 
 @override
 public boolean isenabled() {
 return true;
 }
}

8 . 核心配置,配置springsecurity訪問策略,包括登錄處理,登出處理,資源訪問,密碼基本加密。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package com.wuxicloud.config;
 
import com.wuxicloud.dao.userrepository;
import com.wuxicloud.model.user;
import com.wuxicloud.security.securityuser;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.beans.factory.annotation.autowired;
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.configuration.enablewebsecurity;
import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter;
import org.springframework.security.core.authentication;
import org.springframework.security.core.userdetails.userdetails;
import org.springframework.security.core.userdetails.userdetailsservice;
import org.springframework.security.core.userdetails.usernamenotfoundexception;
import org.springframework.security.crypto.bcrypt.bcryptpasswordencoder;
import org.springframework.security.web.authentication.savedrequestawareauthenticationsuccesshandler;
import org.springframework.security.web.authentication.logout.logoutsuccesshandler;
 
import javax.servlet.servletexception;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
 
/**
 * created by ealenxie on 2018/1/11.
 */
@configuration
@enablewebsecurity
public class websecurityconfig extends websecurityconfigureradapter {
 private static final logger logger = loggerfactory.getlogger(websecurityconfig.class);
 
 @override
 protected void configure(httpsecurity http) throws exception { //配置策略
 http.csrf().disable();
 http.authorizerequests().
 antmatchers("/static/**").permitall().anyrequest().authenticated().
 and().formlogin().loginpage("/login").permitall().successhandler(loginsuccesshandler()).
 and().logout().permitall().invalidatehttpsession(true).
 deletecookies("jsessionid").logoutsuccesshandler(logoutsuccesshandler()).
 and().sessionmanagement().maximumsessions(10).expiredurl("/login");
 }
 
 @autowired
 public void configureglobal(authenticationmanagerbuilder auth) throws exception {
 auth.userdetailsservice(userdetailsservice()).passwordencoder(passwordencoder());
 auth.erasecredentials(false);
 }
 
 @bean
 public bcryptpasswordencoder passwordencoder() { //密碼加密
 return new bcryptpasswordencoder(4);
 }
 
 @bean
 public logoutsuccesshandler logoutsuccesshandler() { //登出處理
 return new logoutsuccesshandler() {
 @override
 public void onlogoutsuccess(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, authentication authentication) throws ioexception, servletexception {
 try {
  securityuser user = (securityuser) authentication.getprincipal();
  logger.info("user : " + user.getusername() + " logout success ! ");
 } catch (exception e) {
  logger.info("logout exception , e : " + e.getmessage());
 }
 httpservletresponse.sendredirect("/login");
 }
 };
 }
 
 @bean
 public savedrequestawareauthenticationsuccesshandler loginsuccesshandler() { //登入處理
 return new savedrequestawareauthenticationsuccesshandler() {
 @override
 public void onauthenticationsuccess(httpservletrequest request, httpservletresponse response, authentication authentication) throws ioexception, servletexception {
 user userdetails = (user) authentication.getprincipal();
 logger.info("user : " + userdetails.getusername() + " login success ! ");
 super.onauthenticationsuccess(request, response, authentication);
 }
 };
 }
 @bean
 public userdetailsservice userdetailsservice() { //用戶登錄實現
 return new userdetailsservice() {
 @autowired
 private userrepository userrepository;
 
 @override
 public userdetails loaduserbyusername(string s) throws usernamenotfoundexception {
 user user = userrepository.findbyusername(s);
 if (user == null) throw new usernamenotfoundexception("username " + s + " not found");
 return new securityuser(user);
 }
 };
 }
}

9.至此,已經基本將配置搭建好了,從上面核心可以看出,配置的登錄頁的url 為/login,可以創建基本的controller來驗證登錄了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.wuxicloud.web;
 
import com.wuxicloud.model.user;
import org.springframework.security.core.authentication;
import org.springframework.security.core.context.securitycontext;
import org.springframework.security.core.context.securitycontextholder;
import org.springframework.security.core.userdetails.userdetails;
import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestmethod;
import org.springframework.web.context.request.requestcontextholder;
import org.springframework.web.context.request.servletrequestattributes;
 
import javax.servlet.http.httpservletrequest;
 
/**
 * created by ealenxie on 2018/1/11.
 */
@controller
public class logincontroller {
 
 @requestmapping(value = "/login", method = requestmethod.get)
 public string login() {
 return "login";
 }
 
 @requestmapping("/")
 public string root() {
 return "index";
 }
 
 public user getuser() { //為了session從獲取用戶信息,可以配置如下
 user user = new user();
 securitycontext ctx = securitycontextholder.getcontext();
 authentication auth = ctx.getauthentication();
 if (auth.getprincipal() instanceof userdetails) user = (user) auth.getprincipal();
 return user;
 }
 
 public httpservletrequest getrequest() {
 return ((servletrequestattributes) requestcontextholder.getrequestattributes()).getrequest();
 }
}

11 . springboot基本的啟動類 application.class

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.wuxicloud;
 
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
 
/**
 * created by ealenxie on 2018/7/11 15:01
 */
@springbootapplication
public class application {
 
 public static void main(string[] args) {
 springapplication.run(application.class, args);
 }
}

11.根據freemark和controller里面可看出配置的視圖為 /templates/index.html和/templates/index.login。所以創建基本的登錄頁面和登錄成功頁面。

login.html

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!doctype html>
<html lang="en">
<head>
 <meta charset="utf-8">
 <title>用戶登錄</title>
</head>
<body>
<form action="/login" method="post">
 用戶名 : <input type="text" name="username"/>
 密碼 : <input type="password" name="password"/>
 <input type="submit" value="登錄">
</form>
</body>
</html>

注意 : 這里方法必須是post,因為get在controller被重寫了,用戶名的name屬性必須是username,密碼的name屬性必須是password

index.html

?
1
2
3
4
5
6
7
8
9
10
11
12
<!doctype html>
<html lang="en">
<head>
 <meta charset="utf-8">
 <title>首頁</title>
 <#assign user=session.spring_security_context.authentication.principal/>
</head>
<body>
歡迎你,${user.username}<br/>
<a href="/logout">注銷</a>
</body>
</html>

注意 : 為了從session中獲取到登錄的用戶信息,根據配置springsecurity的用戶信息會放在session.spring_security_context.authentication.principal里面,根據freemarker模板引擎的特點,可以通過這種方式進行獲取 : <#assign user=session.spring_security_context.authentication.principal/>

12 . 為了方便測試,我們在數據庫中插入一條記錄,注意,從websecurity.java配置可以知道密碼會被加密,所以我們插入的用戶密碼應該是被加密的。

這里假如我們使用的密碼為admin,則加密過后的字符串是 $2a$04$1oiua3yechbxqbji8jamyukznlwzwvfeqjkahnwaeqwnacjt6ukqu

 測試類如下 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.wuxicloud.security;
 
import org.junit.test;
import org.springframework.security.crypto.bcrypt.bcryptpasswordencoder;
 
/**
 * created by ealenxie on 2018/7/11 15:13
 */
public class testencoder {
 
 @test
 public void encoder() {
 string password = "admin";
 bcryptpasswordencoder encoder = new bcryptpasswordencoder(4);
 string enpassword = encoder.encode(password);
 system.out.println(enpassword);
 }
}

測試登錄,從上面的加密的密碼我們插入一條數據到數據庫中。

?
1
insert into `user` values (1, 'd242ae49-4734-411e-8c8d-d2b09e87c3c8', 'ealenxie', '$2a$04$petexpgclkfdln4tyfxk0u8ryazmzdhlaswlx/xxm8hgqar1c892w', 'sssss', 'ssssssssss', 1, 'g', '0:0:0:0:0:0:0:1', '2018-07-11 11:26:27');

13 . 啟動項目進行測試 ,訪問 localhost:8083

 Spring Boot整合Spring Security簡單實現登入登出從零搭建教程

點擊登錄,登錄失敗會留在當前頁面重新登錄,成功則進入index.html

 登錄如果成功,可以看到后臺打印登錄成功的日志 :

Spring Boot整合Spring Security簡單實現登入登出從零搭建教程

 頁面進入index.html :

Spring Boot整合Spring Security簡單實現登入登出從零搭建教程

點擊注銷 ,則回重新跳轉到login.html,后臺也會打印登出成功的日志 :

Spring Boot整合Spring Security簡單實現登入登出從零搭建教程

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://www.cnblogs.com/ealenxie/p/9293768.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产全部视频 | 亚洲精品色婷婷在线影院麻豆 | 亚洲精品97福利在线 | 国产精品资源在线观看网站 | 婷婷综合久久中文字幕 | 护士videossexo另类 | 深夜在线观看网站 | 四虎最新永久在线精品免费 | 福利久草| 金牛网155755水心论坛黄大父母 | 男人曰女人 | 男人视频网站 | 6080伦理久久精品亚洲 | 狠狠干在线观看 | 114级毛片免费观看 1024亚洲天堂 | 亚洲AV 中文字幕 国产 欧美 | 国内精品一区二区三区东京 | 美女扒开腿让男人桶爽免费gif | 亚洲色图亚洲色图 | 国产精品久久久久久久午夜片 | www.尤物在线 | 免费在线视频观看 | 92国产福利久久青青草原 | 男男双性生子产乳高辣h | 青青在线视频免费 | 欧美成狂野欧美在线观看 | 亚洲男女天堂 | 牛牛影院成人免费网页 | 美女班主任下面好爽好湿好紧 | 精品国产一区二区三区在线 | 欧美日韩在线一区 | 欧美日韩一区二区三区在线观看 | 楚乔传第二部免费播放电视连续剧 | 日本精品一区二区三区 | 欧美娇小性xxxx | bnb998八度免费影院丫意浓 | 国产精品青青青高清在线观看 | 亚洲2023无矿砖码砖区 | 日出水了特别黄的视频 | 人人爽人人看 | 操娇妻|