Python 官方文档:入门教程 => 点击学习
目录如何实现同域SSO?代码实现依赖配置控制器拦截器实现界面单点登录,其实看起来不是很复杂,只是细节上的处理,单点区分有三种 同域SSO 同父域SSO
单点登录,其实看起来不是很复杂,只是细节上的处理,单点区分有三种
个人理解:当用户登录访问demo1.lzmvlog.top
时,同时具有访问demo2.lzmvlog.top
的能力,即认证完成一次,可以访问所有系统。
实现方式:可以采用Cookie
实现,即用户在访问一个系统时,携带认证颁发的信息,系统响应是否具有访问资格,否则跳转认证,也可以采用Session
,即Session
共享,校验访问用户是否具有有效的信息,提供访问资格
<!--spring-data-jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
server:
port: 8090
spring:
application:
name: authority
datasource:
url: jdbc:mysql://127.0.0.1:3306/SSO?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
username: root
passWord: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
当用户访问除登录界面时,都需要提前认证,认证完成之后需要跳转到之前访问的路径上,并提供访问别的系统的权限。
实现逻辑,当用户访问任何路径时,都需要通过拦截器的校验,确认拥有访问的权限,才能放行通过,不具有访问权限的,重定向到 登录界面,并保存原有访问的页面路径,验证成功的时候跳转到原有页面
@Controller
public class IndexController {
@Autowired
UserRepository userRepository;
public String url;
@GetMapping("/index")
public String index() {
return "index";
}
@GetMapping("/")
public String index1() {
return "index";
}
@PostMapping("login")
public String login(String username, String password, httpservletResponse response) {
// 用户登录
boolean exists = userRepository.exists(Example.of(new User()
.setUsername(username)
.setPassword(password)));
if (exists) {
Cookie cookie = new Cookie("username", username);
response.addCookie(cookie);
// 如果正常访问即跳转到正常页面
if (StringUtils.isEmpty(url)) {
return "demo1";
}
// 如果之前存在访问的页面,认证完成即跳转会原有的页面
return url;
}
return "index";
}
@GetMapping("demo2")
public String demo2() {
return "demo2";
}
@GetMappi=ng("demo1")
public String demo1() {
return "demo1";
}
}
@Component
public class CookieHandlerInterceptor implements HandlerInterceptor {
@Autowired
UserRepository userRepository;
@Autowired
IndexController indexController;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 获取当前请求得路径 如果不是正常得登录界面请求 登录成功之后需要跳转到原来请求得界面上
String servletPath = request.getServletPath();
// 对不需要拦截得路径进行放行
if ("/index".equals(servletPath) || "/".equals(servletPath) || "/login".equals(servletPath)) {
return true;
}
if (!"/index".equals(servletPath) || !"/".equals(servletPath)) {
indexController.url = servletPath;
}
Cookie[] cookies = request.getCookies();
boolean exists = false;
if (cookies != null) {
for (Cookie cookie : cookies) {
String value = cookie.getValue();
if (!StringUtils.isEmpty(value)) {
exists = userRepository.exists(Example.of(new User()
.setUsername(value)));
}
}
}
if (exists) {
return true;
} else {
response.sendRedirect("/index");
}
return false;
}
}
在SpringBoot2.x
之后不能生效,需要将拦截器添加到拦截器链路中,即:
@Configuration
public class WEBmvcConfig extends WebMvcConfigurationSupport {
@Autowired
private CookieHandlerInterceptor cookieHandlerInterceptor;
@Override
protected void addInterceptors(InterceptorReGIStry registry) {
registry.addInterceptor(this.cookieHandlerInterceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
其实拦截器还有第二种实现方式,即通过Filter
接口实现
@Component
public class CookieFilter extends OncePerRequestFilter {
@Autowired
UserRepository userRepository;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 获取当前请求得路径 如果不是正常得登录界面请求 登录成功之后需要跳转到原来请求得界面上
String servletPath = request.getServletPath();
IndexController indexController = new IndexController();
// 对不需要拦截得路径进行放行
if ("/index".equals(servletPath) || "/".equals(servletPath) || "/login".equals(servletPath)) {
filterChain.doFilter(request, response);
}
if (!"/index".equals(servletPath) || !"/".equals(servletPath)) {
indexController.url = servletPath;
}
Cookie[] cookies = request.getCookies();
boolean exists = false;
if (cookies != null) {
for (Cookie cookie : cookies) {
String value = cookie.getValue();
if (!StringUtils.isEmpty(value)) {
exists = userRepository.exists(Example.of(new User()
.setUsername(value)));
}
}
}
if (exists) {
filterChain.doFilter(request, response);
} else {
response.sendRedirect("/");
}
}
}
其实也可以采用Session
的方式实现,采用共享Session
的方式,我这里只是简单的实现一下,其实在认证时可以结合SpringSecurity
或者shiro
安全框架去整合Jwt
以保证信息的安全
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<div align="center">
<h1>请登录</h1>
<fORM action="/login" method="post">
<span>账号:</span><input name="username" type="text" value="zhang"><br>
<span>密码:</span><input name="password" type="password" value="123456"><br>
<button type="submit" style="margin: 10px 0">登录</button>
</form>
</div>
</body>
</html>
demo1.html
和demo2.html
只需要坐一下简单的区分,知道是哪个页面就行了
同域SSO
其实不是很复杂,只是了解一下整个访问的过程,和需要做的一些限制即可,后续看看做后面两种的实现
即同父域SSO
和跨域SSO
以上就是SpringBoot如何实现同域SSO(单点登录)的详细内容,更多关于SpringBoot 实现同域SSO的资料请关注编程网其它相关文章!
--结束END--
本文标题: SpringBoot如何实现同域SSO(单点登录)
本文链接: https://www.lsjlt.com/news/125795.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0