-
2013-01-16 17:11:59原帖地址:http://blog.csdn.net/xufaxi/article/details/5703516
和利用数据库进行验证类似,LDAP中也是利用登陆名和密码进行验证,LDAP中会定义一个属性password,用来存放用户密码,而登陆名使用较多的都是mail地址。那怎么样才能正确的用LDAP进行身份验证呢,下面是一个正确而又通用的步骤:
1. 从客户端得到登陆名和密码。注意这里的登陆名和密码一开始并没有被用到。
2. 先匿名绑定到LDAP服务器,如果LDAP服务器没有启用匿名绑定,一般会提供一个默认的用户,用这个用户进行绑定即可。
3. 之前输入的登陆名在这里就有用了,当上一步绑定成功以后,需要执行一个搜索,而filter就是用登陆名来构造,形如: "(|(uid=$login)(mail=$login))" ,这里的login就是登陆名。搜索执行完毕后,需要对结果进行判断,如果只返回一个entry,这个就是包含了该用户信息的entry,可以得到该entry的DN,后面使用。如果返回不止一个或者没有返回,说明用户名输入有误,应该退出验证并返回错误信息。
4. 如果能进行到这一步,说明用相应的用户,而上一步执行时得到了用户信息所在的entry的DN,这里就需要用这个DN和第一步中得到的password重新绑定LDAP服务器。
5. 执行完上一步,验证的主要过程就结束了,如果能成功绑定,那么就说明验证成功,如果不行,则应该返回密码错误的信息。
这5大步就是基于LDAP的一个 “两次绑定” 验证方法,下面这个图能更形象的说明这个过程:
为什么基于LDAP进行验证需要“两次”绑定呢,为什么不能取出password然后和输入进行比较呢,试想一下,如果需要读出密码,服务器上的密码存储要么就不加密,直接可以读出,要么客户就需要知道服务器使用的加密方式,这是不安全,也是不好的,服务器不希望加密方式让客户端知道,客户端也不需要知道这么多。而从实际来看,LDAP服务器对于password属性默认都是不可读的,甚至有的服务器根本就不支持password属性可读,遇到这种情况,也就没有办法取得密码了。
还有一个问题就是,为什么我们需要第一次绑定?为什么不直接使用DN呢,首先就是关于这个DN,对于一般的客户端程序,其并不知道具体的DN是什么。再者让用户输入DN,给用户带来不便的同时,验证也带来问题,因为如果输入的是个目录树而不是所期望的DN,在进行绑定时有可能会让服务器产生不可预料的错误。
从上面看来,基于LDAP进行身份验证,最好也是最通用的方法就是 “两次绑定”。
所谓的bind是一个authentication的过程,不要把它想像成“绑定”,既然是认证,就需要一个用户名和密码,openldap中如果出示的用户名和密码错误,服务器会尝试匿名认证,就和匿名ftp一样。当然,在现实配置中可能需要在认证不获得成功就不能做查询操作,这些是在slapd.conf文件中通过设置ACL实现的。
认证所用的用户名和密码为目录树中某个节点的两个属性(用户名和密码),一般情况下,程序会默认使用uid和userPassword属性。写程序进行认证的时候只要提供这个节点的两个属性就可以了。更多相关内容 -
ldap 身份验证的通用步骤
2017-09-14 11:46:33那怎么样才能正确的用LDAP进行身份验证呢,下面是一个正确而又通用的步骤: 1. 从客户端得到登陆名和密码。注意这里的登陆名和密码一开始并没有被用到。 2. 先匿名绑定到LDAP服务器,如果LDAP服务器没和利用数据库进行验证类似, LDAP 中也是利用登陆名和密码进行验证, LDAP 中会定义一个属性 password ,用来存放用户密码,而登陆名使用较多的都是 mail 地址。那怎么样才能正确的用 LDAP 进行身份验证呢,下面是一个正确而又通用的步骤:
1. 从客户端得到登陆名和密码。注意这里的登陆名和密码一开始并没有被用到。
2. 先匿名绑定到LDAP服务器,如果LDAP服务器没有启用匿名绑定,一般会提供一个默认的用户,用这个用户进行绑定即可。
3. 之前输入的登陆名在这里就有用了,当上一步绑定成功以后,需要执行一个搜索,而filter就是用登陆名来构造,形如: "(|(uid=$login)(mail=$login))" ,这里的login就是登陆名。搜索执行完毕后,需要对结果进行判断,如果只返回一个entry,这个就是包含了该用户信息的entry,可以得到该entry的DN,后面使用。如果返回不止一个或者没有返回,说明用户名输入有误,应该退出验证并返回错误信息。
4. 如果能进行到这一步,说明用相应的用户,而上一步执行时得到了用户信息所在的entry的DN,这里就需要用这个DN和第一步中得到的password重新绑定LDAP服务器。
5. 执行完上一步,验证的主要过程就结束了,如果能成功绑定,那么就说明验证成功,如果不行,则应该返回密码错误的信息。
这5大步就是基于LDAP的一个 “两次绑定” 验证方法,下面这个图能更形象的说明这个过程:
为什么基于LDAP进行验证需要“两次”绑定呢,为什么不能取出password然后和输入进行比较呢,试想一下,如果需要读出密码,服务器上的密码存储要么就不加密,直接可以读出,要么客户就需要知道服务器使用的加密方式,这是不安全,也是不好的,服务器不希望加密方式让客户端知道,客户端也不需要知道这么多。而从实际来看,LDAP服务器对于password属性默认都是不可读的,甚至有的服务器根本就不支持password属性可读,遇到这种情况,也就没有办法取得密码了。
还有一个问题就是,为什么我们需要第一次绑定?为什么不直接使用DN呢,首先就是关于这个DN,对于一般的客户端程序,其并不知道具体的DN是什么。再者让用户输入DN,给用户带来不便的同时,验证也带来问题,因为如果输入的是个目录树而不是所期望的DN,在进行绑定时有可能会让服务器产生不可预料的错误。
从上面看来,基于LDAP进行身份验证,最好也是最通用的方法就是 “两次绑定”。
所谓的bind是一个authentication的过程,不要把它想像成“绑定”,既然是认证,就需要一个用户名和密码,openldap中如果出示的用户名和密码错误,服务器会尝试匿名认证,就和匿名ftp一样。当然,在现实配置中可能需要在认证不获得成功就不能做查询操作,这些是在slapd.conf文件中通过设置ACL实现的。
认证所用的用户名和密码为目录树中某个节点的两个属性(用户名和密码),一般情况下,程序会默认使用uid和userPassword属性。写程序进行认证的时候只要提供这个节点的两个属性就可以了。
-
ldap 身份验证
2020-05-29 20:12:23下面是一个正确而又通用的步骤: 1.从客户端得到登录名和密码。注意这里的登录名和密码一开始是没有被用到的。 2.先匿名绑定到LDAP服务器,如果LDAP服务器没有启用匿名绑定,一般会提供一个默认的用户,用这个用户...和利用数据库进行验证类似,LDAP中也是利用登陆名和密码进行验证,LDAP中会定义一个属性password,用来存放用户密码,而登陆名使用较多的都是邮箱地址。
下面是一个正确而又通用的步骤:
1. 从客户端得到登录名和密码。注意这里的登录名和密码一开始是没有被用到的。2. 先匿名绑定到LDAP服务器,如果LDAP服务器没有启用匿名绑定,一般会提供一个默认的用户,用这个用户进行绑定即可。
3. 之前输入的登录名在这里就有用了,当上一步绑定成功以后,需要执行一个搜索,而filter就是用登陆名来构造,例如: "(|(uid=$login)(mail=$login))" ,这里的login就是登录名。搜索执行完毕后,需要对结果进行判断,如果只返回一个entry,这个就是包含了该用户信息的entry,可以得到该entry的DN,后面使用。如果返回不止一个或者没有返回,说明用户名输入有误,应该退出验证并返回错误信息。
4. 如果能进行到这一步,说明用相应的用户,而上一步执行时得到了用户信息所在的entry的DN,这里就需要用这个DN和第一步中得到的password重新绑定LDAP服务器。
5. 执行完上一步,验证的主要过程就结束了,如果能成功绑定,那么就说明验证成功,如果不行,则应该返回密码错误的信息。
这5大步就是基于LDAP的一个 “两次绑定” 验证方法。
为什么基于LDAP进行验证需要“两次”绑定呢,为什么不能取出password然后和输入进行比较呢,试想一下,如果需要读出密码,服务器上的密码存储要么就不加密,直接可以读出,要么客户就需要知道服务器使用的加密方式,这是不安全,也是不好的,服务器不希望加密方式让客户端知道,客户端也不需要知道这么多。而从实际来看,LDAP服务器对于password属性默认都是不可读的,甚至有的服务器根本就不支持password属性可读,遇到这种情况,也就没有办法取得密码了。
还有一个问题就是,为什么我们需要第一次绑定?为什么不直接使用DN呢,首先就是关于这个DN,对于一般的客户端程序,其并不知道具体的DN是什么。再者让用户输入DN,给用户带来不便的同时,验证也带来问题,因为如果输入的是个目录树而不是所期望的DN,在进行绑定时有可能会让服务器产生不可预料的错误。
从上面看来,基于LDAP进行身份验证,最好也是最通用的方法就是 “两次绑定”。所谓的绑定是一个authentication(身份验证)的过程,不要把它想像成“绑定”,既然是认证,就需要一个用户名和密码,openldap中如果出示的用户名和密码错误,服务器会尝试匿名认证,就和匿名ftp一样。当然,在现实配置中可能需要在认证不获得成功就不能做查询操作,这些是在slapd.conf文件中通过设置ACL实现的。认证所用的用户名和密码为目录树中某个节点的两个属性(用户名和密码),一般情况下,程序会默认使用uid和userPassword属性。写程序进行认证的时候只要提供这个节点的两个属性就可以了。
ldap中常见名词解释:
CN:common name 通用名
对象的属性为CN,例如一个用户的名字为:张三,那么“张三”就是一个CN。
O:organizationName 组织名
OU : OrganizationUnit 组织单位
o和ou都是ldap目录结构的一个属性,建立目录的时候可选新建o,ou 等。在配置我司交换设备ldap的时候具体是配置ou,o还是cn等,要具体看ldap服务器的相应目录是什么属性。
UID: userid
对象的属性为uid,例如我司一个员工的名字为:zsq,他的UID为:z02691,ldap查询的时候可以根据cn,也可以根据uid。配置ldap查询的时候需要考虑用何种查询方式。具体设备配置根据何种方式查询由ldap服务器的相关配置来决定。
DC:Domain Component
DC类似于dns中的每个元素,例如h3c.com,“.”符号分开的两个单词可以看成两个DC。
DN:Distinguished Name
类似于DNS,DN与DNS的区别是:组成DN的每个值都有一个属性类型,例如:
H3c.com是一个dns,那么用dn表示为:dc=h3c,dc=com 级别越高越靠后。H3c和com的属性都是DC。
DN可以表示为ldap的某个目录,也可以表示成目录中的某个对象,这个对象可以是用户等。
下面是一个简单的ldap认证流程代码:
import org.junit.Before; import org.junit.Test; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.Control; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; import javax.xml.bind.PropertyException; import java.util.*; public class LdapTest { private final String PROPERTIES_SCOPE = "ldap"; private final String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; private String url = "ldap://192.168.30.254:389"; private String base = "1"; private LdapContext ctx = null; private Control[] connCtls = null; public static LdapContext ctx = null; private final Control[] connCtls = null; @Test public void testUser() { connLDAP(); List<User> list = getUser("users"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("ending"); } @Test public void test() { connLDAP(); } public boolean connLDAP() { Hashtable<String, String> env = new Hashtable<>(); env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY); env.put(Context.PROVIDER_URL, url); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, ldapUserDn); env.put(Context.SECURITY_CREDENTIALS, ldapPassword); try { ctx = new InitialLdapContext(env, connCtls); System.out.println("认证成功!"); return Boolean.TRUE; } catch (javax.naming.AuthenticationException e) { System.out.println("认证失败 :"); e.printStackTrace(); return Boolean.FALSE; } catch (Exception e) { System.out.println("认证出错 : "); e.printStackTrace(); return Boolean.FALSE; } finally { close(); } } public void close() { if (ctx != null) { try { ctx.close(); System.out.println("连接关闭"); } catch (NamingException e) { e.printStackTrace(); } } } public List<User> getUser(String uname) { List<User> users = new ArrayList<>(); HashMap<String, String> map = new HashMap<>(); SearchControls searchCtls = new SearchControls(); searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); //过滤器,可改变查询条件 String searchFilter = "(&(cn=" + uname + ")(objectClass=person))"; String searchBase = "DC=maxcrc,DC=com"; //对象的每个属性名 String[] returnedAtts = {"mail", "cn", "userPassword", "sn", "uid"}; searchCtls.setReturningAttributes(returnedAtts); NamingEnumeration<SearchResult> answer; Map<String, String> mmap = new HashMap<>(); try { answer = ctx.search(searchBase, searchFilter, searchCtls); while (answer.hasMoreElements()) { SearchResult sr = (SearchResult) answer.next(); String name = sr.getName(); User user = new User(); if (name.contains("cn") || name.contains("uid")) { String[] s = name.split(","); String[] cns = s[0].split("="); String cn = cns[cns.length - 1]; mmap.put(cn, sr.getNameInNamespace()); NamingEnumeration<? extends Attribute> attrs = sr.getAttributes().getAll(); while (attrs.hasMore()) { Attribute attr = attrs.next(); switch (attr.getID()) { case "cn": user.setCn(attr.get().toString()); break; case "sn": user.setSn(attr.get().toString()); break; case "mail": user.setMail(attr.get().toString()); break; case "uid": user.setUid(attr.get().toString()); break; case "userPassword": user.setPassword(attr.get().toString()); break; } } users.add(user); } } } catch (NamingException e) { e.printStackTrace(); } mmap.forEach((k, v) -> System.out.println("key : value = " + k + ":" + v)); return users; } }
public class User { private String cn; private String sn; private String mail; private String uid; private String password; public String getCn() { return cn; } public void setCn(String cn) { this.cn = cn; } public String getSn() { return sn; } public void setSn(String sn) { this.sn = sn; } public String getMail() { return mail; } public void setMail(String mail) { this.mail = mail; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "cn='" + cn + '\'' + ", sn='" + sn + '\'' + ", mail='" + mail + '\'' + ", uid='" + uid + '\'' + ", password='" + password + '\'' + '}'; } }
-
身份验证协议和java安全框架
2022-05-16 16:01:08在开发应用程序时,安全性是一个主要问题。在 JAVA 中,有多个安全框架旨在使保护应用程序的过程更快、更容易、更成功。下面是一些通常用于 JAVA 程序、网站和 Web 应用程序的用户身份验证和授权的安全框架。一、身份验证协议
1、OAuth
关于 OAuth实际上是什么存在很多混淆。有些人认为 OAuth 是一种登录流程(例如,当您使用 Google Login 登录应用程序时),有些人认为 OAuth 是一种“安全性的东西”。
首先,OAuth不是API 或服务:它是授权的开放标准,任何人都可以实现它。
更具体地说,OAuth 是应用程序可用来为客户端应用程序提供“安全委托访问”的标准。OAuth通过HTTPS工作,并使用访问令牌而不是凭据对设备、API、服务器和应用程序进行授权。
如今,OAuth 2.0 是使用最广泛的 OAuth 形式。所以,当提起“OAuth”时,指的是OAuth2.0。
OAuth Community Site
https://oauth.net/ OAuth 定义了四个角色:
资源所有者:能够授予对受保护资源的访问权限的实体。当资源所有者是一个人时,它被称为最终用户。
资源服务器:托管受保护资源的服务器,能够接受并使用访问令牌响应受保护的资源请求。
客户:代表受保护资源请求的应用程序资源所有者及其授权。“客户”一词确实不暗示任何特定的实现特征(例如,应用程序是否在服务器、桌面或其他设备上执行设备)。
授权服务器:服务器成功后向客户端颁发访问令牌验证资源所有者并获得授权。
OAuth 2.0是一个框架,用于控制对受保护资源(例如应用程序或一组文件)的授权。OAuth 有点像房子的规则,它规定了一个人在里面可以做什么和不能做什么。
2、SAML
SAML全称是安全断言标记语言(Security Assertion Markup Language)是一个基于XML的开源标准数据格式。用于在不同的安全域之间交换认证和数据授权。在SAML标准定义了身份提供者(IDP)和服务提供者(SP),这两者构成了前面所说的不同的安全域。 SAML是OASIS组织安全服务技术委员会(Security Services Technical Committee)的产品。
SAML解决的最重要的需求是Web端应用的单点登录(SSO)。
SAML 协议主要有三个角色:
SP(Service Provider):向用户提供服务的web 端应用。
IDP(Identity Provide):向SP提供用户身份信息
用户:通过登录IDP获取身份断言,并向SP返回身份断言来使用SP提供的服务。
SAML 有点像房门钥匙。它允许您访问该设施。
3、OpenID Connect
OpenID Connect 基于 OAuth 2.0 协议构建,并使用称为 ID 令牌的附加 JSON Web 令牌 (JWT) 来标准化 OAuth 2.0 留给选择的区域,例如范围和端点发现。它特别专注于用户身份验证,并广泛用于在消费者网站和移动应用程序上启用用户登录。
它允许客户端根据授权服务器执行的身份验证验证最终用户的身份,并以可互操作和类似 REST 的方式获取有关最终用户的基本配置文件信息。
OpenID Connect 允许所有类型的客户端(包括基于 Web、移动和 JavaScript 的客户端)请求和接收有关经过身份验证的会话和最终用户的信息。该规范套件是可扩展的,允许参与者在对他们有意义的情况下使用可选功能,例如身份数据加密、OpenID 提供者发现和会话管理。
OpenID Connect | OpenID
https://openid.net/connect/ oAuth2.0协议是用来获取对受保护的资源比如某些web api调用所需的access token的。OpenID Connect则利用了oAuth2.0的这个流程来允许RP(三方应用)获取用户的身份信息。这些信息是以JWT形式进行交互的id token。同时,OpenID Connect还允许RP用获取id token时由OP一并返回的access token来进一步获取用户的个人信息,比如email、手机号码等。
非常常见的就是我们经常使用的是第三方登陆等。
4、kerberos
Kerberos (KRB5) 是一种成熟、灵活、开放且非常安全的网络身份验证协议。Kerberos 包括身份验证、相互身份验证、消息完整性以及机密性和委托功能。它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证。麻省理工学院可免费实施该协议。Kerberos 也可用于许多商业产品。
MIT的Kerberos网址。
Kerberos: The Network Authentication Protocol
https://web.mit.edu/kerberos/ Kerberos 由 MIT 创建,用于解决网络安全问题。Kerberos 协议使用强加密,因此客户端可以通过不安全的网络连接向服务器证明其身份(反之亦然)。在客户端和服务器使用 Kerberos 证明他们的身份之后,他们还可以加密他们的所有通信,以确保他们开展业务时的隐私和数据完整性。
Kerberos提供了一个集中的认证服务器。在 Kerberos 中,身份验证服务器和数据库用于客户端身份验证。Kerberos 作为第三方可信服务器运行,称为密钥分发中心 (KDC)。网络上的每个用户和服务都是一个主体。
Kerberos 的主要组件有:
身份验证服务器 (AS):身份验证服务器执行票证授予服务的初始身份验证和票证。
数据库:Authentication Server 验证用户在数据库中的访问权限。
Ticket Granting Server (TGS):Ticket Granting Server 为服务器签发票据基本步骤
1、客户端从密钥分发中心 (KDC) 请求身份验证票 (TGT)。
2、KDC 验证凭据并发回加密的 TGT 和会话密钥。
3、客户端请求访问服务器上的应用程序。应用程序服务器的票证请求被发送到由客户端的 TGT 和身份验证器组成的 KDC。
4、KDC 向用户返回票证和会话密钥。
5、票证被发送到应用程序服务器。一旦收到票证和身份验证器,服务器就可以对客户端进行身份验证。
6、服务器使用另一个身份验证器回复客户端。接收到这个验证器后,客户端可以验证服务器。
要是使用Kerberos,必须单独修改每个应用。
尽管 Kerberos 在数字世界中随处可见,但它通常用于依赖强大的身份验证和审计功能的安全系统中。Kerberos 用于 Posix、Active Directory、NFS 和 Samba 身份验证。它也是 SSH、POP 和 SMTP 的替代身份验证系统。
5、LDAP
LDAP 服务提供通用目录服务。它可以用来存储各种信息。所有 LDAP 服务器都有一些系统来控制谁可以读取和更新目录中的信息。
要访问 LDAP 服务,LDAP 客户端首先必须对服务进行身份验证。也就是说,它必须告诉 LDAP 服务器谁将访问数据,以便服务器可以决定允许客户端查看和执行什么操作。如果客户端向LDAP服务器认证成功,那么当服务器随后收到客户端的请求时,会检查是否允许客户端执行该请求。这个过程称为访问控制。
LDAP 标准提出了 LDAP 客户端可以向 LDAP 服务器进行身份验证的方法( RFC 2251 和 RFC 2829)。这些将在 LDAP 身份验证部分和 身份验证机制部分进行一般性讨论。本课还包含有关如何使用 匿名、 简单和 SASL身份验证机制的说明。
LDAP 服务的另一个安全方面是支持使用安全通道与客户端进行通信,例如发送和接收包含密码和密钥等机密的属性。LDAP 服务器为此目的使用 SSL。
典型应用场景
网络服务:DNS服务
统一认证服务:
Linux PAM (ssh, login, cvs. . . )
Apache访问控制
各种服务登录(ftpd, php based, perl based, python based. . . )
个人信息类,如地址簿
服务器信息,如帐号管理、邮件服务等6、RADIUS
远程身份验证拨入用户服务 ( RADIUS ) 是一种网络协议,它为连接和使用网络服务的用户提供集中的身份验证、授权和记帐(AAA 或 Triple A)管理。
RADIUS 身份验证在用户请求通过远程访问服务器 (RAS) 访问网络资源时开始。用户输入用户名和密码,由RADIUS服务器加密,然后通过身份验证过程发送。
然后 RADIUS 服务器通过使用身份验证方案验证数据来检查信息的准确性。这是通过将用户提供的信息与本地存储的数据库进行比较或引用外部资源(如 Active Directory 服务器)来完成的。
然后,RADIUS 服务器将通过接受、挑战或拒绝用户来响应。个人用户可能会被授予受限访问权限,而不会影响其他用户。在质询的情况下,RADIUS 服务器会向用户请求其他信息以验证他们的用户 ID - 这可能是 PIN 或二级密码。在拒绝的情况下,用户将被无条件地拒绝对 RADIUS 协议的所有访问。
7、CAS
中央身份验证服务 (CAS) 是 Web 的单点登录协议。其目的是允许用户访问多个应用程序,同时仅提供一次凭据(例如用户 ID 和密码),同时允许应用程序验证用户身份,而无需访问这些凭据(例如密码)。CAS 这个名字也指的是实现这个协议的一个软件包,它最近已经成为 Shibboleth IdP v3 包的一部分。由于 Gluu CE 包含 Shibboleth 以添加对 SAML 协议流的支持,因此它包含了所有与 CAS 相关的功能。CAS 协议的最新版本是 3。
CAS | Apereo
https://www.apereo.org/projects/cas 如果不是旧的系统中有使用,可能现在应用的感觉就较少了。
8、JWT
JWT 是 JSON Web Token 的缩写,它是一种紧凑的 URL 安全方式,用于表示要在两方之间传输的声明。JWT 中的声明被编码为使用 JSON Web 签名 (JWS) 进行数字签名的 JSON 对象。
简而言之,JWT token 是我们在发出网络请求以安全地传递数据并确保它没有被篡改时传入 header 或 url 的字符串。
JWT 令牌的一种非常常见的用途,也是您可能只应该使用 JWT 的用途,是作为一种API 身份验证机制。
JWT是一种令牌格式,OAuth 2.0 是一种协议(可选使用 JWT 作为令牌格式),实际上很多应用都是OAuth2结合JWT使用。
JWT 令牌包括以下元素
1、标头:算法和令牌类型
{ "alg":"HS256", "typ”:"JWT" }
然后,这个 JSON 被 Base64Url 编码以形成 JWT 的第一部分。
'use strict'; var header = { "alg": "HS256", "typ": "JWT" }; var enc_header = Buffer.from(JSON.stringify(header)).toString('base64'); // ► "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
2、有效数据
{ "sub":"1234567890", "name":"John Doe", "admin":true }
然后对有效负载进行 Base64Url 编码以形成 JSON Web 令牌的第二部分。
'use strict'; var payload = { "exp": "2019-02-14", "message": "roses are red" }; var enc_payload = Buffer.from(JSON.stringify(payload)).toString('base64'); // ► eyJleHAiOiIyMDE5LTAyLTE0IiwibmFtZSI6IkpvaG4gRG9lIn0
3、签名
要创建签名部分,您必须获取编码的标头、编码的有效数据、标头中指定的算法,并对其进行签名。
'use strict'; const crypto = require('crypto'); var jwt_secret = "secret"; // enc_header and enc_payload are computed earlier var signature = crypto.createHmac('sha256', jwt_secret).update(enc_header +"."+ enc_payload).digest('base64'); // ► 6C46KAaZGp6RjbSqGllfdQF7g8vXCp02NTSrz-PzeoI
最终的 JWT 令牌如下所示
var token = `${enc_header}.${enc_payload}.${signature}`; // ► eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIyMDE5LTAyLTE0IiwibWVzc2FnZSI6InJvc2VzIGFyZSByZWQifQ.0u-mkgLo5479CPjJJ4mXCwn2RW4dFT12fiYiopRWsZw
JWT 令牌用于身份验证而不是加密,因此即使不知道密钥,也有人可以读取您的标头和有效负载数据。但是在收到令牌后,您可以使用您的密钥再次对标头和有效负载进行签名,并将其与收到的签名进行比较,以检测令牌或消息的篡改。
二、Java安全框架
在开发应用程序时,安全性是一个主要问题。在 JAVA 中,有多个安全框架旨在使保护应用程序的过程更快、更容易、更成功。下面是一些通常用于 JAVA 程序、网站和 Web 应用程序的用户身份验证和授权的安全框架。
1、Spring Security
因为spring security的功能很多,并且支持oauth2,所以非常的重量级,不如Shiro轻量级。但是Spring Security 提供一流的保护,以抵御 CSRF 和会话固定等攻击。
Spring SecurityLevel up your Java code and explore what Spring can do for you.
https://spring.io/projects/spring-security Spring Security 模块与所有其他 Spring 功能无缝集成。Spring Security 提供了多种身份验证技术,包括 HTTP BASIC、HTTP Digest、HTTP x-509、LDAP、用户名/密码、OpenID、预先建立的请求标头、JAAS、Kerberos 等等。
它还提供了多种授权机制,包括授权Web请求、授权方法调用、授权访问域对象实例等。
2、Apache Shiro
Apache Shiro 于 2004 年作为 JSecurity 诞生,并于 2008 年被 Apache 基金会接受。迄今为止,它已经发布了许多版本。
Apache Shiro | Simple. Java. Security.
https://shiro.apache.org/ Apache Shiro 是一个开源安全框架,提供身份验证、授权、密码学和会话管理。Shiro 框架具有直观、易用等特性,同时也能提供健壮的安全性,虽然它的功能不如 Spring Security 那么强大,但是在常规的企业级应用中,也非常常用。
Shiro 有四个基石——身份验证、授权、会话管理和加密。
身份验证:有时称为“登录”,这是证明用户身份的行为。
授权:访问控制的过程,即决定谁访问什么。
会话管理:管理用户特定的会话,即使在非 Web 或 EJB 应用程序中也是如此。
密码学:通过使用加密算法保持数据安全且易于使用。此外,Shiro 还提供了额外的功能来解决不同环境下面临的安全问题。
Web 支持:Shiro 的 Web 支持 API 可以轻松帮助保护 Web 应用程序。
缓存:缓存是 Apache Shiro 中的第一层公民,以确保安全操作快速高效。
并发:Apache Shiro 使用其并发特性来支持多线程应用程序。
测试:存在测试支持以帮助您编写单元测试和集成测试。
“运行身份”:允许用户假设另一个用户身份的功能(如果允许)。它有时在管理脚本时很有用。
“记住我”:在会话中记住用户的身份,这样用户在强制登录时只需要登录。3、JAAS
Java Authentication and Authorization Services,JAAS是Java安全框架的一部分,从JDK版本 1.4 开始直接集成到 JAVA 开发工具包中。
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jaas/JAASRefGuide.html
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jaas/JAASRefGuide.html JAAS 框架主要关注应用程序中用户的身份验证和授权。JAAS 是一个可插入的框架,允许应用程序保持独立于身份验证技术。实施 JAAS 安全框架时不需要修改应用程序。可以使用多种形式的身份验证,包括用户名/密码、语音、指纹、生物识别等。
使用 JAAS 的授权与 JAVA SE 访问控制模块一起工作。如果用户认证成功,JAAS 框架会根据相关主体检查用户凭证。
-
如何使用oAuth2对SPA用户进行身份验证?
2021-03-22 16:34:03隐式拨款你是对的,隐式授权类型看起来不合适 ...我认为“隐含流动”不合适的原因是缺少通过提供客户端密钥和授权代码的客户端身份验证步骤 . 安全性降低 .访问令牌作为URL片段发送回(以便令牌不会转到服务器),这将... -
基于LDAP进行验证-方法和问题
2012-04-20 14:53:19随着LDAP的发展和趋于成熟,基于LDAP的应用也越来越广泛,这些应用往往都离不开身份验证。这里就来说一下基于LDAP的目录服务进行验证。 和利用数据库进行验证类似,LDAP中也是利用登陆名和密码进行验证,LDAP中会... -
ldap python_Python和LDAP
2020-06-23 22:13:58在本文中,我们将展示如何安装在Amazon EC2虚拟机上运行的OpenLDAP实例,设置Apache / LDAP身份验证,然后使用Python执行CRUD或创建,读取,更新和删除操作。 重要的是要注意,LDAP可以安装在Fedora,Ubuntu,Red ... -
ldap 协议
2019-12-31 17:01:32ldap目录服务 日常生活中,或者开发过程中,需要管理的目录有很多。 如:人员组织管理,电话簿,地址簿,字典表等。 提供管理和查询目录信息的服务就是目录服务。 有很多厂商实现了目录服务,但是对外提供的接口... -
交叉验证选择最佳参数_如何为您的公司选择最佳的身份验证即服务提供商
2020-07-19 08:27:30如何为您的公司选择最佳的身份验证即服务提供商 (How to choose the best Authentication as a Service Provider for your company) Have you ever wondered how to choose an authentication serv... -
ldap配置_AIX上的LDAP配置管理和故障排除
2020-06-22 07:13:58它提供了通用访问所需的一致的身份验证和授权服务。 为了实现集中式安全性,许多客户使用IBM Directory Server(IBMAIX®支持的集中式安全性机制)。 为了实现万无一失的IBM Directory Server配置并准备使用,您... -
ldap 权限控制
2020-01-02 16:44:13其他所有通过身份验证的用户只有读权限,其余人没有任何权限。 如果没有 access to 规则或匹配的 by 指令,则拒绝访问。只有经过显式声明才能授予访问权限。如果根本没有声明任何规则,默认规则是管理员具有写... -
mediawiki_将MediaWiki与LDAP集成
2020-06-29 10:26:25因为许多PHP解决方案都提供了LDAP身份验证支持,所以可以选择LDAP创建中央用户和组存储库。 在开始之前,您需要满足以下条件: PHP 5.1或更高版本(有关所需PHP版本的详细信息,请咨询... -
k8s 身份验证
2018-03-24 17:26:59与其他身份验证协议(LDAP,SAML,Kerberos,备用x509方案等)的集成可以使用身份验证代理或身份验证webhook完成。 X509 客户端证书 x509 是一种通用证书格式 启动apiserver时,添加 --client-ca-... -
LDAP系列三用户权限控制
2019-05-24 18:12:15其他所有通过身份验证的用户只有读权限,其余人没有任何权限。 如果没有 access to 规则或匹配的 by 指令,则拒绝访问。只有经过显式声明才能授予访问权限。如果根本没有声明任何规则,默认规则是管理员具有写... -
LDAP与数据库的比较
2016-06-28 20:42:18摘要 LDAP(Lightweight Directory Access Protocol),轻量级目录访问协议。 在企业员工查询信息方面简化了很多流程,非常方便。...LDAP(Lightweight Directory Access Protocol),轻量级 -
使用Apache Shiro进行身份认证-LDAP两次绑定认证
2012-04-23 11:25:28通常在根据LDAP进行身份验证时会采取以下三种方法: 1、利用一个LDAP用户的...基于LDAP进行身份验证,最好也是最通用的方法就是 “两次绑定”。这种方法的步骤以及优点可参看我的另一篇博客:基于LDAP进行验证-方法 -
Shiro学习-身份验证
2018-03-15 12:50:20Shiro学习-身份验证作者:vashon时间:2018-03-15简介Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Spring Security,可能没有 Spring Security 做的功能强大... -
LDAP与PHP的要点
2020-08-17 00:31:17(Verify the Installation) With that done, let’s quickly verify that everything’s working, by running the following command: 完成此操作后,我们通过运行以下命令来快速验证一切是否正常: ldapsearch -...