会话是指用户登入系统后,系统会记住该用户的登录状态,他可以在系统连续操作直到退出系统的过程。认证的目的是对系统资源的保护,每次对资源的访问,系统必须得知道是谁在访问资源,才能对该请求进行合法性拦截。
因此,在认证成功后,一般会把认证成功的用户信息放入Session中,在后续的请求中,系统能够从Session中获取到当前用户,用这样的方式来实现会话机制。
1、增加会话控制
首先在UserDto中定义一个SESSION_USER_KEY ,作为Session中存放登录用户信息的key。
package com.uncle.security.springmvc.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Set;
/**
* @program: security-springmvc
* @description:
* @author: 步尔斯特
* @create: 2021-07-22 23:25
*/
@Data
@AllArgsConstructor
public class UserDto {
public static final String SESSION_USER_KEY = "_user";
//用户身份信息
private String id;
private String username;
private String password;
private String fullname;
private String mobile;
}
然后修改Logincontroller,认证成功后,将用户信息放入当前会话。并增加用户登出方法,登出时将session置为失效。
package com.uncle.security.springmvc.controller;
import com.uncle.security.springmvc.model.AuthenticationRequest;
import com.uncle.security.springmvc.model.UserDto;
import com.uncle.security.springmvc.service.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
/**
* @program: security-springmvc
* @description:
* @author: 步尔斯特
* @create: 2021-07-22 23:33
*/
@RestController
public class LoginController {
@Autowired
AuthenticationService authenticationService;
@RequestMapping(value = "/login",produces = "text/plain;charset=utf-8")
public String login(AuthenticationRequest authenticationRequest, HttpSession session){
UserDto userDto = authenticationService.authentication(authenticationRequest);
//存入session
session.setAttribute(UserDto.SESSION_USER_KEY,userDto);
return userDto.getUsername() +"登录成功";
}
@GetMapping(value = "/logout",produces = {
"text/plain;charset=UTF-8"})
public String logout(HttpSession session){
session.invalidate();
return "退出成功";
}
}
2、增加测试资源
修改Logincontroller ,增加测试资源1 ,它从当前会话session中获取当前登录用户,并返回提示信息给前台。
package com.uncle.security.springmvc.controller;
import com.uncle.security.springmvc.model.AuthenticationRequest;
import com.uncle.security.springmvc.model.UserDto;
import com.uncle.security.springmvc.service.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
/**
* @program: security-springmvc
* @description:
* @author: 步尔斯特
* @create: 2021-07-22 23:33
*/
@RestController
public class LoginController {
@Autowired
AuthenticationService authenticationService;
@RequestMapping(value = "/login",produces = "text/plain;charset=utf-8")
public String login(AuthenticationRequest authenticationRequest, HttpSession session){
UserDto userDto = authenticationService.authentication(authenticationRequest);
//存入session
session.setAttribute(UserDto.SESSION_USER_KEY,userDto);
return userDto.getUsername() +"登录成功";
}
@GetMapping(value = "/logout",produces = {
"text/plain;charset=UTF-8"})
public String logout(HttpSession session){
session.invalidate();
return "退出成功";
}
@GetMapping(value = "/r/r1",produces = {
"text/plain;charset=UTF-8"})
public String r1(HttpSession session){
String fullname = null;
Object object = session.getAttribute(UserDto.SESSION_USER_KEY);
if(object == null){
fullname = "匿名";
}else{
UserDto userDto = (UserDto) object;
fullname = userDto.getFullname();
}
return fullname+"访问资源r1";
}
}
3、测试
未登录情况下直接访问测试资源/r/r1 :
成功登录的情况下访问测试资源/r/r1 :
退出,访问地址/logout
测试结果说明,在用户登录成功时,该用户信息已被成功放入session ,并且后续请求可以正常从session中获取当前登录用户信息,退出时,session失效,再次访问为匿名访问,符合预期结果。