目录
一、概念
二、认证流程
三、鉴权流程
四、缺点
五、实现代码
5.1 项目结构
5.2 pom.xml
5.3 application.yml
5.4 login.html
5.5 entity
5.5.1 UserDto
5.5.2 AuthenticationRequest.java
5.6 config
5.6.1 WebAppConfugurer
5.6.2 SimleAuthenticationInterceptor
5.7 service
5.7.1 AuthenticationService
5.7.2 AuthenticationServiceImpl
5.8 Controller
5.8.1 LoginController
5.8.2 UserController
5.9 效果
六、参考文章
Session 是一种HTTP存储机制,目的是为无状态的HTTP提供的持久机制。所谓 Session 认证只是简单的把 User 信息存储到 Session 里,因为 SID 的不可预测性,暂且认为是安全的。这是一种认证手段。
用户输入其登录信息
服务器验证信息是否正确,并创建一个session,然后将其存储在数据库中
服务器为用户生成一个sessionId,将具有sesssionId的Cookie将放置在用户浏览器中
在后续请求中,会根据数据库验证sessionID,如果有效,则接受请求
一旦用户注销应用程序,会话将在客户端和服务器端都被销毁
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.6.2
com.session.test
sessiontest
0.0.1-SNAPSHOT
sessiontest
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
org.apache.maven.plugins
maven-resources-plugin
3.1.0
server:
port: 8080
spring:
thymeleaf:
mode: LEGACYHTML5
main:
#默认支持名称相同的bean的覆盖
allow-bean-definition-overriding: true
user:
key: SESSION_USER_KEY
用户登录
package com.session.test.sessiontest.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Set;
/**
* @author sujm
* @date 2021/12/22 16:50
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDto {
private String id;
private String username;
private String password;
private String fullname;
private String mobile;
private Set authorities;
}
package com.session.test.sessiontest.entity;
import lombok.Data;
/**
* @author sujm
* @date 2021/12/22 16:49
*/
@Data
public class AuthenticationRequest {
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
}
package com.session.test.sessiontest.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc
@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {
@Bean
SimpleAuthenticationInterceptor simpleAuthenticationInterceptor() {
return new SimpleAuthenticationInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 可添加多个
registry.addInterceptor(simpleAuthenticationInterceptor()).addPathPatterns("/r/*");
}
}
package com.session.test.sessiontest.config;
import com.session.test.sessiontest.entity.UserDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Component
@Slf4j
public class SimpleAuthenticationInterceptor implements HandlerInterceptor {
@Value("${user.key}")
private String userKey;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//读取会话信息
System.out.println(userKey);
Object object = request.getSession().getAttribute(userKey);
if (object == null) {
log.info("请登录");
writeContent(response, "请登录");
return false;
}
log.info("object ={}",object);
UserDto user = (UserDto) object;
//请求的url
String requestURI = request.getRequestURI();
if (user.getAuthorities().contains("p1") && requestURI.contains("/r1")) {
return true;
}
if (user.getAuthorities().contains("p2") && requestURI.contains("/r2")) {
return true;
}
log.info("权限不足,拒绝访问");
writeContent(response, "权限不足,拒绝访问");
return false;
}
private void writeContent(HttpServletResponse response, String msg) throws IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.print(msg);
writer.close();
}
}
package com.session.test.sessiontest.service;
import com.session.test.sessiontest.entity.AuthenticationRequest;
import com.session.test.sessiontest.entity.UserDto;
public interface AuthenticationService {
UserDto authentication(AuthenticationRequest authenticationRequest);
}
package com.session.test.sessiontest.service;
import com.session.test.sessiontest.entity.AuthenticationRequest;
import com.session.test.sessiontest.entity.UserDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.*;
@Service
@Slf4j
public class AuthenticationServiceImpl implements AuthenticationService {
//用户信息
private Map userMap = new HashMap<>();
{
Set authorities1 = new HashSet<>();
authorities1.add("p1");
Set authorities2 = new HashSet<>();
authorities2.add("p2");
userMap.put("zhangsan", new UserDto("1010", "zhangsan", "123", "张 三", "133443", authorities1));
userMap.put("lisi", new UserDto("1011", "lisi", "456", "李四", "144553", authorities2));
userMap.put("admin", new UserDto("1012", "admin", "123", "李四", "144553",null));
}
@Override
public UserDto authentication(AuthenticationRequest authenticationRequest) {
Optional.ofNullable(authenticationRequest).orElseThrow(() -> new RuntimeException("账号信息为空"));
String password = authenticationRequest.getPassword();
String username = authenticationRequest.getUsername();
if (StringUtils.isEmpty(password) || StringUtils.isEmpty(username)) {
throw new RuntimeException("用户名密码为空");
}
UserDto userDto = getUserDto(username);
if (ObjectUtils.isEmpty(userDto)) {
throw new RuntimeException("用户信息不存在");
}
return userDto;
}
public UserDto getUserDto(String username) {
return userMap.get(username);
}
}
package com.session.test.sessiontest.controller;
import com.session.test.sessiontest.entity.AuthenticationRequest;
import com.session.test.sessiontest.entity.UserDto;
import com.session.test.sessiontest.service.AuthenticationService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
/**
* @author sujm
* @date 2021/12/22 17:02
*/
@Controller
public class LoginController {
@Resource
private AuthenticationService authenticationService;
@Value("${user.key}")
private String userKey;
@GetMapping("/goLogin")
public String goLogin() {
return "user/login";
}
@PostMapping(path = "/login", produces = "text/html;charset=UTF-8")
@ResponseBody
public String login(AuthenticationRequest authenticationRequest, HttpSession session) {
UserDto userDetails = authenticationService.authentication(authenticationRequest);
System.out.println("登录" + userKey);
session.setAttribute(userKey, userDetails);
return userDetails.getUsername() + "登录成功";
}
@GetMapping(value = "logout")
@ResponseBody
public String logout(HttpSession session) {
session.invalidate();
return "退出成功";
}
}
package com.session.test.sessiontest.controller;
import com.session.test.sessiontest.entity.UserDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RestController
public class UserController {
@Value("${user.key}")
private String userKey;
/*** 测试资源1 * @param session * @return
* 登陆成功之后,直接访问这个地址测试即可
* */
@GetMapping(value = "/r/r1")
public String r1(HttpSession session) {
String fullname = null;
Object userObj = session.getAttribute(userKey);
if (userObj != null) {
fullname = ((UserDto) userObj).getFullname();
} else {
fullname = "匿名";
}
return fullname + " 访问资源1";
}
@GetMapping(value = "/r/r2",produces = {"text/html;charset=UTF-8"})
public String r2(HttpSession session) {
String fullname = null;
Object userObj = session.getAttribute(userKey);
if (userObj != null) {
fullname = ((UserDto) userObj).getFullname();
} else {
fullname = "匿名";
}
return fullname + " 访问资源2";
}
}
基于jwt和session用户认证的区别和优缺点_Java笔记虾-CSDN博客 基于Session的认证方式_一个人的江湖-CSDN博客_session认证 基于session和token的身份认证方案 - 开拖拉机的蜡笔小新 - 博客园