spring security
是由 spring 提供的对于认证和授权的框架,可以对接口进行权限的控制,让一些不想公开的数据可以被保护
Oauth2.0
单点登录
随着我们一个微服务的出现,我们用 spring security 不再能满足我们对于登录的需求。因为微服务中,我们做登录往往需要每一个微服务都去做认证,这样子会导致每当我换个模块访问,就需要登录一次,非常影响用户的体验。于是**单点登录( SSO )**的概念出现了,单点登录就是我登录过一次之后就会将我的用户信息保存下来,去访问其他资源服务的时候会去自动做认证,查看有没有权限
第三方认证登录
随着我们的发展,很多网站都需要我们注册登录,往往注册会需要填写很多的信息,十分的麻烦,于是就出现了通过第三方登录。第三方登录是将你之前注册在第三方中的信息去授权给你要登录的网站或者 app,这样就省去了我们需要注册的操作。Oauth2.0就可以使用我们的第三方认证登录。
Oauth2.0的认证流程
Oauth2 授权方式
- 授权码(authorization-code)
- 隐藏式(implicit)
- 密码式(password)
- 客户端凭证(client credentials)
JWT
JWT (JSON WEB TOKEN)
jwt是一种特殊格式的token,包含了3个部分
- 头部 Header
- 载荷 Payload
- 签名Signature
头部和载荷都是可以通过base64解码的,可以拿到权限和各种信息
签名是通过私钥生成的,只有有对应的公钥才能解码
传统的不包含JWT的认证会需要由我们认证服务去认证,因为令牌是由认证服务颁发的
使用JWT令牌就可以让我们资源服务通过公钥去解码JWT令牌,从而去验证令牌的合法性
生成私钥
keytool -genkeypair -alias 别名 -keyalg RSA -keypass 密码 -keystore 文件名称以.keystore结尾 -storepass keystore密码
导出公钥
下载openssl http://slproweb.com/products/Win32OpenSSL.html 配置好环境变量(系统变量的Path 添加下载的bin的路径)
keytool -list -rfc --keystore 私钥名称 | openssl x509 -inform pem -pubkey
然后输入你的密码,就可以拿到公钥和认证信息了
生成JWT令牌
@SpringBootTest
@RunWith(SpringRunner.class)
public class UcenterAuthApplicationTest {
//生成一个jwt令牌
@Test
public void testCreateJwt(){
//证书文件
String key_location = "sy.keystore";
//密钥库密码
String keystore_password = "sykeystore";
//访问证书路径
ClassPathResource resource = new ClassPathResource(key_location);
//密钥工厂
KeyStoreKeyFactory keyStoreKeyFactory = new
KeyStoreKeyFactory(resource, keystore_password.toCharArray());
//密钥的密码,此密码和别名要匹配
String keypassword = "sy";
//密钥别名
String alias = "sykey";
//密钥对(密钥和公钥)
KeyPair keyPair = keyStoreKeyFactory.getKeyPair(alias,
keypassword.toCharArray());
//私钥
RSAPrivateKey aPrivate = (RSAPrivateKey) keyPair.getPrivate();
//定义payload信息
Map<String, Object> tokenMap = new HashMap<>();
tokenMap.put("id", "1");
tokenMap.put("name", "mmmmores");
tokenMap.put("roles", "admin");
tokenMap.put("ext", "1");
//生成jwt令牌
Jwt jwt = JwtHelper.encode(JSON.toJSONString(tokenMap), new
RsaSigner(aPrivate));
//取出jwt令牌
String token = jwt.getEncoded();
System.out.println("token="+token);
}
}
令牌校验
@SpringBootTest
@RunWith(SpringRunner.class)
public class UcenterAuthApplicationTest {
//资源服务使用公钥验证jwt的合法性,并对jwt解码
@Test
public void testVerify(){
//jwt令牌
String token =
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHQiOiIxIiwicm9sZXMiOiJyMDEscjAyIiw
ibmFtZSI6ImxpbHkiLCJpZCI6IjEyMyJ9.es-XS2lPBHls_LDPuKFQuUjOf1xuX9-
6CCw45TiVXXZHBO06CKtxSaSo7rypPTI4sqlEQYfCBqdHM9t5k77DQkTZeMsmAX93gTBKDPmkIDh9HymLL1MZsy89ez38FXCrX71Gu874bNkS7lt_mKfNGnhhkPMX75Tj4cMgTWcPOE3mtX7LiCNECXOPorF5gyVJpiPTT6KyLcDz9WjyAcwx-5kwR5hFe5x0_g4H5XoSzyYu9EpRY0FcBiUJUB5WQLIi9BbhsJcbumotAXkMtnQdoLVWY4-k0kl45-3NbJuKoaoeupQb1mSGsAzZxQo__XbD_6jgyYu4pWRPRXkaMxw";
//公钥
String publickey = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg4Ik50ILQn7l0AxyWnohpsGSM0CvQsf/i
hQ1414nFBjDQ6/3Sz8nFVt9JMl1mZfcIyYBp9SMOuauqrOKkMbM/Whm94MCBJbTrL/8Y4ZKoxfbGJ
gGJuhRcwouWZxw4a8lXGcVl8OCs4pq62Gkff6ilmYAz9BOt4+QFM2dGAjL8WWgGeFBuinPMzZ3BDB
clg10tF5S8ZN/G4CjT8bvw4KX6840VThiqehjp7od2jPOZTNkFIF7OZGMbZp2+F2BhQDAe2HTs9CV
iQCpvywjZOktDe1IL07qdkq5F+Vu0YZmKp4sXTk6Y3Oi0LLKbGR5e/q0nGFo53VL7iqc74HpekAbh
QIDAQAB-----END PUBLIC KEY-----";
//校验jwt
Jwt jwt = JwtHelper.decodeAndVerify(token, new
RsaVerifier(publickey));
//获取jwt令牌中自定义的内容
String claims = jwt.getClaims();
System.out.println("jwt中自定义的内容:"+claims);
//jwt令牌
String encoded = jwt.getEncoded();
System.out.println("jwt令牌"+encoded);
}
}