spring-security–基础–4.1–案例:简单登陆登出
代码位置
https://gitee.com/DanShenGuiZu/learnDemo/tree/master/spring-security-learn
1、介绍
通过SpringSecurity实现以下功能:
- 用户访问资源页面,未登陆跳转登陆页面。
- 登陆失败给出提示,并还在登陆页面。
- 登陆成功跳转资源页面。
2、代码
2.1、结构
2.2、依赖
<!--security begin-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-thymeleaf</artifactId>
</dependency>
<!--security end-->
2.2、核心代码
MvcConfig
package com.feizhou.oauth.hello;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 视图配置
*
* @author zhoufei
* @class: MvcConfig
* @date 2020/10/24 21:03
* @Verson 1.0 -2020/10/24 21:03
* @see
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry){
//请求/home或者/ 跳转到home页面
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
//请求/hello 跳转到hello页面
registry.addViewController("/hello").setViewName("hello");
//请求/login 跳转到login页面
registry.addViewController("/login").setViewName("login");
}
}
MyPasswordEncoder
package com.feizhou.oauth.hello;
/**
* 密码加密规则,这里采用明文,不加密規則
*
* @author zhoufei
* @class: MyPasswordEncoder
* @date 2020/10/25 10:08
* @Verson 1.0 -2020/10/25 10:08
* @see
*/
import org.springframework.security.crypto.password.PasswordEncoder;
public class MyPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence){
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s){
return s.equals(charSequence.toString());
}
}
WebSecurityConfig
package com.feizhou.oauth.hello;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//web url 拦截规则
@Override
protected void configure(HttpSecurity http)throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
// .successForwardUrl("/hello")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)throws Exception {
//可以设置内存指定的登录的账号密码,指定角色
//不加.passwordEncoder(new MyPasswordEncoder()),就不是以明文的方式进行匹配,会报错
// auth.inMemoryAuthentication().withUser("admin").password("admin").roles("USER");
//.passwordEncoder(new MyPasswordEncoder())。
//这样,页面提交时候,密码以明文的方式进行匹配。
auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder()).withUser("admin").password("admin").roles("USER");
}
}
hello.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Hello World!</title>
</head>
<body>
<h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
<form th:action="@{/logout}" method="post">
<input type="submit" value="Sign Out"/>
</form>
</body>
</html>
home.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example</title>
</head>
<body>
<h1>Welcome! home</h1>
<p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
</body>
</html>
login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example </title>
</head>
<body>
<div th:if="${param.error}">
Invalid username and password.
</div>
<div th:if="${param.logout}">
You have been logged out.
</div>
<form th:action="@{/login}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>
3、测试
3.1、访问首页
http://localhost:8080/
3.2、点击here,尝试访问受限的页面:/hello,由于未登录,结果被强制跳转到登录页面
3.3、输入正确的用户名和密码之后,跳转到之前想要访问的/hello页面
3.4、点击Signout退出按钮,访问:/logout,回到登录页面
3.5、用错误用户密码登陆
4、核心代码解读
//web url 拦截规则
@Override
protected void configure(HttpSecurity http)throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
- authorizeRequests: 授权请求
- antMatchers:url匹配规则
- permitAll:允许
- anyRequest:其他请求
- authenticated:要验证
- formLogin:表单认证相关的配置
- loginPage(“/login”):跳转登录页面,当未登陆的用户访问受保护的资源时,都跳转登录页面。
- logout:默认指定"/logout"为退出页面。
- and():对应了一个模块的配置,等同于xml配置中的结束标签