单点登录及登录相关功能1
登录的面临问题
- 安全问题,登录面临的安全问题
- 用户体验,快捷登录如短信登陆等
- 并发问题 ,用户增加面临很多用户同时登录
- 移动设备登录
- 第三方账号登陆,通过其他社交帐号等其他第三方登录
- 单点登录和统一身份认证,用户需要一次登录访问多个应用程序
- 法律法规和合规性, 登录后数据加密和隐私政策
- 可扩展性和灵活性,登录功能不断扩展和升级可能需要支持
定义:什么是单点登录
简称SSO(Single sign-on)
- 登录后可以访问该系统的各个应用
- 登陆后要存储用户的登陆状态
- 登陆后提供令牌和会话标识
- 存储已有用户的身份凭证
如何实现和解决上面的问题
spring会出手
- 安全问题:Spring Security 是一个强大的安全框架,它提供了多种身份验证和授权机制,可以帮助保护登录功能免受各种安全威胁,如密码泄露、SQL 注入、XSS 和 CSRF 攻击。
- 用户体验问题:Spring 框架提供了丰富的 Web 开发特性,如 Spring MVC 和 Spring WebFlux,可以帮助构建用户友好的登录界面。这些框架提供了灵活的视图解析和模板引擎,允许开发者创建响应式和易于使用的界面。
- 高并发问题:Spring 提供了一系列工具和技术来处理高并发访问,如 Spring Boot 的自动配置和嵌入式服务器,以及 Spring Cloud 中的微服务架构和负载均衡策略。这些特性有助于构建高性能和可扩展的登录系统。
- 移动设备适配:Spring Mobile 是一个针对移动设备优化的扩展,它提供了适配不同移动设备屏幕尺寸和操作系统的功能,使得登录功能在移动设备上能够提供良好的用户体验。
社交登录和第三方登录:Spring Social 是一个用于与社交网络集成的框架,它提供了与微信、QQ、 - 微博等社交平台登录的功能。Spring Social 简化了与第三方身份提供者的集成过程。
单点登录和统一身份认证:Spring Security 支持单点登录(SSO)和联合身份验证(Federated Identity),这有助于减少用户在多个应用系统中重复登录的繁琐。Spring Cloud 中的 Spring Cloud OAuth2 提供了构建单点登录系统的解决方案。 - 法律法规和合规性:Spring 框架本身并没有直接解决法律法规和合规性问题的功能,但是它提供了一个灵活的开发框架,可以在其上构建符合法律法规和合规性要求的应用程序。例如,你可以利用 Spring 的 AOP(面向切面编程)特性来实现数据加密、日志记录和访问控制等功能。
可扩展性和灵活性:Spring 框架的核心是 IoC(控制反转)和 DI(依赖注入)容器,它允许开发者以松散耦合的方式构建应用程序。这种方式提供了极大的可扩展性和灵活性,使得登录功能可以方便地集成新的认证方式、支持多因素认证或与其他系统进行集成。
认证授权
拦截器实现session认证与授权
1.配置spring session
<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session</artifactId>
</dependency>
- 配置session策略
spring.session.store-type=jdbc
spring.session.jdbc.table-name=spring_session
spring.session.jdbc.initialize-schema=embedded
- 登陆表单
<form action="/login" method="post"><input type="text" name="username" placeholder="Username" required><input type="password" name="password" placeholder="Password" required><button type="submit">Login</button>
</form>
拦截器
5. 创建拦截器
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class AuthenticationInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 检查Session中是否存在用户名,如果不存在,则重定向到登录页面if (request.getSession().getAttribute("username") == null) {response.sendRedirect("/login");return false;}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在请求处理之后执行的操作,这里可以添加一些日志记录或者其他处理逻辑}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在整个请求完成后执行的操作,这里可以进行一些资源清理工作}
}
- 注册拦截器
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/dashboard/**") // 保护需要认证的路径.excludePathPatterns("/login", "/css/**", "/js/**"); // 排除不需要认证的路径}
}
- 设置授权拦截器
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class AuthorizationInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 假设我们通过Session中的"role"属性来检查用户的角色String role = (String) request.getSession().getAttribute("role");if (role == null ||!role.equals("ADMIN")) {// 用户没有ADMIN角色,重定向到拒绝访问页面或返回错误信息response.sendRedirect("/access-denied");return false;}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在请求处理之后执行的操作,这里可以添加一些日志记录或者其他处理逻辑}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在整个请求完成后执行的操作,这里可以进行一些资源清理工作}
}
- 注册拦截器
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthorizationInterceptor()).addPathPatterns("/admin/**") // 保护需要ADMIN角色的路径.excludePathPatterns("/login", "/css/**", "/js/**"); // 排除不需要认证的路径}
}
- 登录和登出并授权
@Controller
public class LoginController {@PostMapping("/login")public String login(@RequestParam String username, @RequestParam String password, HttpSession session) {// 这里应该进行实际的用户认证逻辑,例如检查数据库// 假设用户名为"admin"的用户具有ADMIN角色if ("admin".equals(username) && "test".equals(password)) {// 认证成功,将用户名和角色存储在Session中session.setAttribute("username", username);session.setAttribute("role", "ADMIN");return "redirect:/dashboard"; // 重定向到仪表板页面} else {// 认证失败,返回登录页面并显示错误消息return "redirect:/login?error";}}@GetMapping("/logout")public String logout(HttpSession session) {// 注销用户,移除Session中的用户名和角色session.removeAttribute("username");session.removeAttribute("role");return "redirect:/login"; // 重定向到登录页面}
}
- 设置session最大存活时间
server.servlet.session.timeout=30m
- 动态设置session存活时间
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.stereotype.Component;import javax.servlet.ServletContext;
import javax.servlet.ServletException;@Component
public class SessionTimeoutInitializer implements ServletContextInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {// 设置Session超时时间为60分钟servletContext.setSessionTimeout(60 * 60);}
}