【安全】简单解析统一身份认证:介绍、原理和实现方法

深入解析统一身份认证:介绍、原理和实现方法
  • * 导语
    
    •   * 统一身份认证是什么
      
      • 统一身份认证的原理
      • 统一身份认证的实现
    • 结语:

导语

随着互联网的发展和各种在线服务的普及,用户在不同的应用和平台上需要进行多次身份验证。为了简化用户的登录和减少重复操作,统一身份认证(Single Sign-
On,简称SSO)技术应运而生。本文将简单介绍统一身份认证的概念、原理和实现方法,希望能帮助你更好地理解和应用该技术。

统一身份认证是什么

统一身份认证是一种用户身份验证的解决方案,它允许用户在一个身份验证服务提供商的帮助下,只需一次登录就可以访问多个应用或网站。SSO的目标是简化用户的登录流程,提高用户体验,并减少用户需要记忆和管理的密码数量。

统一身份认证的原理

统一身份认证的核心原理是通过在不同应用和平台之间共享身份验证信息,使得用户在一个应用中进行登录后,可以无需再次输入密码或进行身份验证即可访问其他应用。以下是主要的原理和流程:

用户登录:用户在某个应用上输入用户名和密码进行登录。
身份验证:该应用向统一身份认证系统发送身份验证请求。
令牌颁发:统一身份认证系统验证用户的身份,并为该用户生成一个令牌。
令牌返回:统一身份认证系统将令牌返回给应用。
令牌验证:应用通过与统一身份认证系统通信,验证令牌的有效性。
访问授权:一旦令牌验证成功,应用将授权用户访问相关资源。
第三部分:统一身份认证的实现方法
统一身份认证可以通过多种技术和协议来实现。以下是几种常见的实现方法:

统一身份认证的实现

基于令牌的实现:使用令牌作为身份验证凭据进行跨应用认证。令牌可以是基于 JSON Web Token(JWT)或其他自定义格式的加密令牌。

基于SAML的实现:Security Assertion Markup Language(SAML)是一种基于 XML
的标准,用于在不同安全域之间交换身份认证和授权信息。

基于OAuth的实现:OAuth是一种开放标准,用于授权第三方应用访问用户资源,也可以用于实现统一身份认证。允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。
OAuth 2.0协议提供了不同的授权流程和令牌类型。OAuth 2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth
2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。

基于OpenID Connect的实现:OpenID Connect是基于OAuth
2.0的一种认证协议,它添加了身份认证的功能,使得应用可以获取用户的身份信息。

单点登录服务器(SSO Server)的实现:通过搭建一个中心化的身份验证服务器,各个应用都将身份验证的责任交给该服务器,实现统一身份认证。

结语:

统一身份认证技术可以帮助用户在多个应用和平台上简化登录过程,提高用户体验。本文介绍了统一身份认证的概念、原理和实现方法,希望能帮助你更好地去理解和应用该技术。
随着技术的不断发展,统一身份认证将在互联网应用中发挥越来越重要的作用,为用户提供更便捷和安全的登录体验。

如有错误,还请多多指教!
转载或者引用本文内容请注明来源及原作者:橘足轻重;

学习计划安排


我一共划分了六个阶段,但并不是说你得学完全部才能上手工作,对于一些初级岗位,学到第三四个阶段就足矣~

这里我整合并且整理成了一份【282G】的网络安全从零基础入门到进阶资料包,需要的小伙伴可以扫描下方CSDN官方合作二维码免费领取哦,无偿分享!!!

如果你对网络安全入门感兴趣,那么你需要的话可以

点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

①网络安全学习路线
②上百份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥HW护网行动经验总结
⑦100个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年CTF夺旗赛题解析

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.引言 几乎所有的Web项目开发都需要客户端验证,尤其是JavaScript的使用,JS结合Html和CSS占据了网页展现市场,不管采用什么技术我们在网页看到的东西最终生成都是这些代码所表示含义。 Web应用如此广泛,其中客户端与服务端交互时所消耗的资源及响应时间,频繁的刷新页面使得人机交互体验极为不好,而对每个页面使用客户端处理技术无疑又加大项目开发周期,脚本调试及修改维护的工作量将占用大量的开发时间,验证控件须对每个控件的元素进行设置且会对页面整体的布局带来影响,占据着页面布局空间的位置,综合考虑及项目整体风格的统一等多种因素中,总得有个折中的考虑。ChkInputs.js应运而生,使用它不需要编写多少代码,只需对验证元素简单配置一下即可,使用方便,也不会影响页面的布局,并可以精确判断客户端输入框的长度、必填、数据类型(整数型、浮点型、字母型、数字字母混合型)和下拉框等,及对需要验证的控件分组验证等。同时提供许多常用的公共函数如类似C#中Trim()方法等。 使用ChkInputs.js,会将光标定位到验证不通过的控件上,若控件上有文本同时将其文本选中高亮度显示,不会刷新页面,只有当所有验证通过时才会将结果提交到后台处理,可以使用鼠标或纯键盘及相结合的方式来操作。 2.ChkInputs.js的使用: ChkInputs.js的使用极为方便,你可以直接将自定义属性像这样添加在Web页面, <input name="TextBox1" type="text" id="TextBox1" chinese="测试输入框" maxsize="6" nullable="no" datatype="number" /> 也可以在后台代码里这样添加,如在.net下.aspx.cs代码里这样写: this.TextBox1.Attributes.Add("chinese", "测试输入框");//控件名称 this.TextBox1.Attributes.Add("maxsize", "6");//控件接受的字符长度大小 this.TextBox1.Attributes.Add("nullable", "no");//不可为空,默认可为空 this.TextBox1.Attributes.Add("datatype", "number");//控件数据类型 两者代码是一样的,不过一般在后台代码(.cs)写好写,因为这样写有利于项目的维护修改。当页面的控件元素都设置好时,客户端代码通常只需这样写即可: 首先在页面head区域内定义一个这样的JS函数 <script language="javascript"> //例一,全部验证,比较常用,基本满足一般所有的验证功能 function CheckInfoAll() { return verifyAll(document.getElementById("form1")); } </script> 然后在需要验证的按钮上这样写 OnClientClick="return CheckInfoAll();" 或者使用onfocus ="rerurn CheckInfoAll();"或 onmousedown="rerurn CheckAll();" onkeydown="if(event.keyCode == 13){rerurn CheckAll();}" 后面的各种使用根据你的偏好选择使用。 除此之外,还可以指定验证及分组验证。指定验证如: return verifyInput(document.getElementById("TextBox1")); 分组验证同一个页面的元素最多可分六组(够用的了),各组之间互不影响,示例代码如下: //验证页面所属组group1="group1"的元素 function CheckAllGroup1() { return verifyAllByGroup1(document.getElementById("form1"),"group1") } 其它更多的使用详细代码可见附件示例代码所示。 3.ChkInputs的结构及原理: 这里先简要介绍一下文档对象模型(DOM)与树状结构,DOM可以让HTML元素与其属性,利用JS程序来控制。有两种方法将JS程序用于文档的元素:通过元素的名称和通过树状结构。这两个方法并非独立的,可能同时存在于相同的脚步中。 基本上对象是可以用脚步控制,或者可编程元素,拥有属性(Property)、事件(Event)以及方法(Method)。JS把所有网页元素、屏幕上可见的画面区域,以及浏览器的窗口都当成可编程的对象。所以,只要通过程序,你就可以控制这些对象的属性,执行其方法,以及捕捉这些事件等。 对象都有属性,有的属性就是对象本身。试想将人体当成对象,如果以分级的方式来看,人体对象有个躯干属性,而躯干有个心脏属性,心脏里还有心室属性。这些身体的零件都属于属性,而且全部都与人体对象之间有逻辑化的层次关系。 同样地,任何JavaScript这类面向对象程序语言的元素,也都是对象。这些对象都通过分级系统,作为主体的一部分。举例来说,浏览器窗口是一个对象,包含了几个文档对象,这些对象进而形成其他对象,依此类推,这个分级会变得很长。 由于面向对象的本质,JavaScript允许对象、对象的属性以及其事件都通过脚本来控制。也因为大部分网页浏览器都支持JavaScript,所以它是网页设计时最适合的客户端语言。ChkInputs.js就是通过JavaScript并结合DOM对象的自定义的属性而编写的。当使用时,ChkInputs.js会自动遍历DOM的元素,逐个检测直到所以验证完毕为止,由于事件触发在客户端响应非常及时,不会刷新页面。 该函数库提供许多函数库,就不一一列举了,这里举几个代表性的函数例子加以解释说明,先介绍一个频率用的最多的函数,如函数verifyAll,定义如下: function verifyAll(myform) {…………..} 参数myform指代验证的表单,可以比作验证树DOM的根,之后的JavaScript会遍历所有元素(elements),逐个检验,若没有设置验证则直接跳过,若有一个验证不通过,都不会将表单提交,并将光标定位到该处(focus()),若有文本同时高亮度选中该文本(select())。同样其他函数的原理也是类似。 另外,其他函数如数据长度的验证,是验证内容的实际字节的长度,即汉字两个字节英文及数字两个字节,判断依据ASCII值,计算机在设计字符存储的时候就是超过一个字节的ASCII字符都是以两个字节存放的。同时JavaScript提供了Scripting. FileSystemObject对象,GetFileSize(…)可直接取得待上传文件的字节大小,但也有限制就是客户端浏览须启用ActiveX插件,若没有启用时,会提示用户按步骤设置。CancelClientEvent()是使用事件冒泡阻止了事件的继续执行,同时设置返回值,最终成功阻止事件的继续往后执行,当在客户端触发一要回发的按钮事件是,想在程序里结束让其继续执行时,以往则不是很好处理,如Enter键,这里此方法则大显用武之地。 附有ChkInputs.js完整的源代码及实例代码。
Spring Cloud Gateway是一个基于Spring Boot 2.x的API网关,可以作为微服务架构中的统一入口,提供路由、转发、负载均衡、限流、降级、统一认证和鉴权等功能。在实现统一认证和鉴权时,可以结合Spring Security和JWT来实现。 具体实现步骤如下: 1. 引入Spring Security和JWT的依赖 在Spring Cloud Gateway的pom.xml文件中,引入Spring Security和JWT的依赖: ``` <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring-security.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring-security.version}</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jjwt.version}</version> </dependency> ``` 2. 配置Spring Security 在Spring Cloud Gateway的配置类中,配置Spring Security: ``` @Configuration @EnableWebFluxSecurity public class SecurityConfig { @Autowired private JwtAuthenticationManager jwtAuthenticationManager; @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { return http.csrf().disable() .authorizeExchange() .pathMatchers("/login").permitAll() .anyExchange().authenticated() .and() .addFilterAt(new JwtAuthenticationFilter(jwtAuthenticationManager), SecurityWebFiltersOrder.AUTHENTICATION) .build(); } } ``` 在上面的配置中,首先禁用了CSRF防护,然后配置了登录接口不需要认证,其它接口都需要认证。最后添加了一个JWT认证过滤器。 3. 配置JWT 在Spring Cloud Gateway的配置类中,配置JWT: ``` @Configuration public class JwtConfig { @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; @Bean public JwtAuthenticationManager jwtAuthenticationManager() { return new JwtAuthenticationManager(secret); } @Bean public JwtTokenGenerator jwtTokenGenerator() { return new JwtTokenGenerator(secret, expiration); } } ``` 在上面的配置中,配置了JWT的密钥和过期时间,并创建了JWT的管理器和生成器。 4. 实现登录接口 实现登录接口,生成JWT并返回给客户端: ``` @RestController public class LoginController { @Autowired private JwtTokenGenerator jwtTokenGenerator; @PostMapping("/login") public Mono<ResponseEntity<Map<String, String>>> login(@RequestBody LoginRequest loginRequest) { // 验证用户名和密码 if (validateUsernameAndPassword(loginRequest)) { // 生成JWT String token = jwtTokenGenerator.generateToken(loginRequest.getUsername()); // 返回JWT Map<String, String> responseBody = new HashMap<>(); responseBody.put("token", token); return Mono.just(ResponseEntity.ok(responseBody)); } else { return Mono.just(ResponseEntity.status(HttpStatus.UNAUTHORIZED).build()); } } private boolean validateUsernameAndPassword(LoginRequest loginRequest) { // 验证用户名和密码逻辑 } } ``` 在上面的代码中,先验证用户名和密码是否正确,如果正确则生成JWT并返回给客户端,否则返回401未授权状态码。 5. 实现JWT认证过滤器 实现JWT认证过滤器,从请求头中获取JWT并验证: ``` public class JwtAuthenticationFilter extends AuthenticationWebFilter { public JwtAuthenticationFilter(JwtAuthenticationManager jwtAuthenticationManager) { super(jwtAuthenticationManager); } @Override protected Mono<Void> onAuthSuccess(Authentication authentication, ServerWebExchange exchange) { return super.onAuthSuccess(authentication, exchange); } @Override protected Mono<Void> onAuthFailure(AuthenticationException e, ServerWebExchange exchange) { return super.onAuthFailure(e, exchange); } @Override public Mono<Void> filter(ServerWebExchange exchange, AuthenticationFilterChain chain) { String token = extractToken(exchange.getRequest().getHeaders().getFirst("Authorization")); if (StringUtils.isEmpty(token)) { return chain.filter(exchange); } else { JwtAuthenticationToken jwtAuthenticationToken = new JwtAuthenticationToken(token); return super.filter(exchange, chain) .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(jwtAuthenticationToken)); } } private String extractToken(String header) { // 从Authorization头中提取JWT } } ``` 在上面的代码中,先从请求头中提取JWT,如果JWT为空则直接调用下一个过滤器,否则创建JwtAuthenticationToken并将其设置到SecurityContext中。 6. 实现JWT认证管理器 实现JWT认证管理器,验证JWT是否正确: ``` public class JwtAuthenticationManager implements ReactiveAuthenticationManager { private final String secret; public JwtAuthenticationManager(String secret) { this.secret = secret; } @Override public Mono<Authentication> authenticate(Authentication authentication) { String token = authentication.getCredentials().toString(); try { Jws<Claims> claimsJws = Jwts.parser().setSigningKey(secret).parseClaimsJws(token); String username = claimsJws.getBody().getSubject(); return Mono.just(new JwtAuthenticationToken(username, token)); } catch (JwtException e) { return Mono.error(e); } } } ``` 在上面的代码中,使用JWT解析解析JWT,并验证签名和过期时间,如果验证通过则创建JwtAuthenticationToken。 7. 实现JWT认证令牌 实现JWT认证令牌: ``` public class JwtAuthenticationToken extends AbstractAuthenticationToken { private final String token; private final String username; public JwtAuthenticationToken(String token) { super(Collections.emptyList()); this.token = token; this.username = null; } public JwtAuthenticationToken(String username, String token) { super(Collections.emptyList()); this.token = token; this.username = username; setAuthenticated(true); } @Override public Object getCredentials() { return token; } @Override public Object getPrincipal() { return username; } } ``` 在上面的代码中,实现了AbstractAuthenticationToken的两个抽象方法,并添加了一个token和username属性。 8. 配置路由规则 最后,配置路由规则,启用Spring Cloud Gateway: ``` @Configuration public class GatewayConfig { @Autowired private JwtTokenGenerator jwtTokenGenerator; @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("login", r -> r.path("/login") .uri("http://localhost:8080/login")) .route("hello", r -> r.path("/hello") .filters(f -> f.requestHeader("Authorization", "Bearer " + jwtTokenGenerator.generateToken("user"))) .uri("http://localhost:8081/hello")) .build(); } } ``` 在上面的配置中,配置了两个路由规则,一个是登录接口,另一个是hello接口,hello接口需要通过JWT认证才能访问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值