Spring Security OAuth2 实现使用JWT
https://yq.aliyun.com/articles/263390
1、Maven 配置
首先,我们需要在我们的pom.xml中添加spring-security-jwt依赖项。
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-jwt</artifactId>
</dependency>
我们需要为Authorization Server和Resource Server添加spring-security-jwt依赖项。
2、授权服务器
接下来,我们将配置我们的授权服务器使用JwtTokenStore - 如下所示
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(tokenStore()).accessTokenConverter(accessTokenConverter()).authenticationManager(authenticationManager);}@Beanpublic TokenStore tokenStore() {return new JwtTokenStore(accessTokenConverter());}@Beanpublic JwtAccessTokenConverter accessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey("123");return converter;}@Bean@Primarypublic DefaultTokenServices tokenServices() {DefaultTokenServices defaultTokenServices = new DefaultTokenServices();defaultTokenServices.setTokenStore(tokenStore());defaultTokenServices.setSupportRefreshToken(true);return defaultTokenServices;}
}
请注意,在JwtAccessTokenConverter中使用了一个对称密钥来签署我们的令牌 - 这意味着我们需要为资源服务器使用同样的确切密钥。
4、资源服务器
现在,我们来看看我们的资源服务器配置 - 这与授权服务器的配置非常相似:
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {@Overridepublic void configure(ResourceServerSecurityConfigurer config) {config.tokenServices(tokenServices());}@Beanpublic TokenStore tokenStore() {return new JwtTokenStore(accessTokenConverter());}@Beanpublic JwtAccessTokenConverter accessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey("123");return converter;}@Bean@Primarypublic DefaultTokenServices tokenServices() {DefaultTokenServices defaultTokenServices = new DefaultTokenServices();defaultTokenServices.setTokenStore(tokenStore());return defaultTokenServices;}
}
请记住,我们将这两个服务器定义为完全独立且可独立部署的服务器。这就是我们需要在新配置中再次声明一些相同的bean的原因。
5、令牌中的自定义声明
现在让我们设置一些基础设施,以便能够在访问令牌中添加一些自定义声明。框架提供的标准声明都很好,但大多数情况下我们需要在令牌中使用一些额外的信息来在客户端使用。 我们将定义一个TokenEnhancer来定制我们的Access Token与这些额外的声明。 在下面的例子中,我们将添加一个额外的字段“组织”到我们的访问令牌 - 与此CustomTokenEnhancer:
public class CustomTokenEnhancer implements TokenEnhancer {@Overridepublic OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {Map<String, Object> additionalInfo = new HashMap<>();additionalInfo.put("organization", authentication.getName() + randomAlphabetic(4));((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);return accessToken;}
}
然后,我们将把它连接到我们的授权服务器配置 - 如下所示:
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancerChain).authenticationManager(authenticationManager);
}@Bean
public TokenEnhancer tokenEnhancer() {return new CustomTokenEnhancer();
}
有了这个新的配置启动和运行 - 这是一个令牌令牌有效载荷看起来像:
{"user_name": "john","scope": ["foo","read","write"],"organization": "johnIiCh","exp": 1458126622,"authorities": ["ROLE_USER"],"jti": "e0ad1ef3-a8a5-4eef-998d-00b26bc2c53f","client_id": "fooClientIdPassword"
}
5.1、在JS客户端使用访问令牌
最后,我们要在AngualrJS客户端应用程序中使用令牌信息。我们将使用angular-jwt库。 所以我们要做的就是在index.html中使用“组织”声明:
<p class="navbar-text navbar-right">{{organization}}</p><script type="text/javascript"src="https://cdn.rawgit.com/auth0/angular-jwt/master/dist/angular-jwt.js">
</script><script>
var app = angular.module('myApp', ["ngResource","ngRoute", "ngCookies", "angular-jwt"]);app.controller('mainCtrl', function($scope, $cookies, jwtHelper,...) {$scope.organiztion = "";function getOrganization(){var token = $cookies.get("access_token");var payload = jwtHelper.decodeToken(token);$scope.organization = payload.organization;}...
});
6、不对称的KeyPair
在我们以前的配置中,我们使用对称密钥来签署我们的令牌:
@Bean
public JwtAccessTokenConverter accessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey("123");return converter;
}
我们还可以使用非对称密钥(公钥和私钥)来执行签名过程。
6.1、生成JKS Java KeyStore文件
我们首先使用命令行工具keytool生成密钥 - 更具体地说.jks文件:
keytool -genkeypair -alias mytest -keyalg RSA -keypass mypass -keystore mytest.jks -storepass mypass
该命令将生成一个名为mytest.jks的文件,其中包含我们的密钥 - 公钥和私钥。 还要确保keypass和storepass是一样的。
6.2、导出公钥
接下来,我们需要从生成的JKS中导出我们的公钥,我们可以使用下面的命令来实现:
keytool -list -rfc --keystore mytest.jks | openssl x509 -inform pem -pubkey
示例回应如下所示:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp
OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2
/5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3
DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR
xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr
lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK
eQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
MIIDCzCCAfOgAwIBAgIEGtZIUzANBgkqhkiG9w0BAQsFADA2MQswCQYDVQQGEwJ1
czELMAkGA1UECBMCY2ExCzAJBgNVBAcTAmxhMQ0wCwYDVQQDEwR0ZXN0MB4XDTE2
MDMxNTA4MTAzMFoXDTE2MDYxMzA4MTAzMFowNjELMAkGA1UEBhMCdXMxCzAJBgNV
BAgTAmNhMQswCQYDVQQHEwJsYTENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAICCtlreMdhLQ5eNQu736TrDKrmTMjsrXjtkbFXj
Cxf4VyHmL4nCq9EkM1ZKHRxAQjIhl0A8+aa4o06t0Rz8tv+ViQQmKu8h4Ey77KTM
urIr1zezXWBOyOaV6Pyh5OJ8/hWuj9y/Pi/dBP96sH+o9wylpwICRUWPAG0mF7dX
eRC4iBtf4BKswtH2ZjYYX6wbccFl65aVA09Cn739EFZj0ccQi10/rRHtbHlhhKnj
iy+b10S6ps2XAXtUWfZEEJuN/mvUJ+YnEkZw30wHrENwq5QFiSpdpHFlNR8CasPn
WUUmdV+JBFzTMsz3TwWxplOjB3YacsCO0imU+5l+AQ51CnkCAwEAAaMhMB8wHQYD
VR0OBBYEFOGefUBGquEX9Ujak34PyRskHk+WMA0GCSqGSIb3DQEBCwUAA4IBAQB3
1eLfNeq45yO1cXNl0C1IQLknP2WXg89AHEbKkUOA1ZKTOizNYJIHW5MYJU/zScu0
yBobhTDe5hDTsATMa9sN5CPOaLJwzpWV/ZC6WyhAWTfljzZC6d2rL3QYrSIRxmsp
/J1Vq9WkesQdShnEGy7GgRgJn4A8CKecHSzqyzXulQ7Zah6GoEUD+vjb+BheP4aN
hiYY1OuXD+HsdKeQqS+7eM5U7WW6dz2Q8mtFJ5qAxjY75T0pPrHwZMlJUhUZ+Q2V
FfweJEaoNB9w9McPe1cAiE+oeejZ0jq0el3/dJsx3rlVqZN+lMhRJJeVHFyeb3XF
lLFCUGhA7hxn2xf3x1JW
-----END CERTIFICATE-----
我们只取得我们的公钥,并将其复制到我们的资源服务器src / main / resources / public.txt中
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp
OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2
/5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3
DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR
xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr
lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK
eQIDAQAB
-----END PUBLIC KEY-----
6.3、Maven 配置
接下来,我们不希望JMS文件被maven过滤进程拾取 - 所以我们将确保将其排除在pom.xml中:
<build><resources><resource><directory>src/main/resources</directory><filtering>true</filtering><excludes><exclude>*.jks</exclude></excludes></resource></resources>
</build>
如果我们使用Spring Boot,我们需要确保我们的JKS文件通过Spring Boot Maven插件添加到应用程序classpath - addResources:
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><addResources>true</addResources></configuration></plugin></plugins>
</build>
6.4、授权服务器
现在,我们将配置JwtAccessTokenConverter使用mytest.jks中的KeyPair,如下所示:
@Bean
public JwtAccessTokenConverter accessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("mytest.jks"), "mypass".toCharArray());converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mytest"));return converter;
}
6.5、资源服务器
最后,我们需要配置我们的资源服务器使用公钥 - 如下所示:
@Bean
public JwtAccessTokenConverter accessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();Resource resource = new ClassPathResource("public.txt");String publicKey = null;try {publicKey = IOUtils.toString(resource.getInputStream());} catch (final IOException e) {throw new RuntimeException(e);}converter.setVerifierKey(publicKey);return converter;
}
Spring Security OAuth2 实现使用JWT相关推荐
- 搭建认证服务器 - Spring Security Oauth2.0 集成 Jwt 之 【密码认证流程】 总结
在搭建介绍流程之前,确保您已经搭建了一个 Eureka 注册中心,因为没有注册中心的话会报错(也有可能我搭建的认证服务器是我项目的一个子模块的原因):Request execution error. ...
- Spring Security OAuth2实现使用JWT
在Spring Security Oauth2-授权码模式(Finchley版本)一文中介绍了OAuth2的授权码模式的实现,本文将在这篇文章的基础上使用JWT生成token.关于JWT的介绍可以参考 ...
- 搭建认证服务器 - Spring Security Oauth2.0 集成 Jwt 之 【授权码认证流程】 总结
在搭建介绍流程之前,确保您已经搭建了一个 Eureka 注册中心,因为没有注册中心的话会报错(也有可能我搭建的认证服务器是我项目的一个子模块的原因):Request execution error. ...
- Spring Security OAuth2:整合jwt
接着上一篇博客:https://www.cnblogs.com/wwjj4811/p/14505081.html 1|0JWT介绍 JSON Web Token(JWT)是一个开放的行业标准(RFC ...
- Spring Security OAuth2整合JWT
文章目录 1. Spring Security 与 OAuth2 2. Spring Security OAuth2的配置和使用 ①:引入依赖 ②:配置 spring security ③:配置授权服 ...
- Spring Security OAuth2 单点登录和登出
文章目录 1. 单点登录 1.1 使用内存保存客户端和用户信息 1.1.1 认证中心 auth-server 1.1.2 子系统 service-1 1.1.3 测试 1.2 使用数据库保存客户端和用 ...
- java oauth sso 源码_基于Spring Security Oauth2的SSO单点登录+JWT权限控制实践
概 述 在前文<基于Spring Security和 JWT的权限系统设计>之中已经讨论过基于 Spring Security和 JWT的权限系统用法和实践,本文则进一步实践一下基于 Sp ...
- 基于 Spring Security OAuth2和 JWT 构建保护微服务系统
我们希望自己的微服务能够在用户登录之后才可以访问,而单独给每个微服务单独做用户权限模块就显得很弱了,从复用角度来说是需要重构的,从功能角度来说,也是欠缺的.尤其是前后端完全分离之后,我们的用户信息不一 ...
- 《深入理解 Spring Cloud 与微服务构建》第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统
<深入理解 Spring Cloud 与微服务构建>第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统 文章目录 <深入理解 Spring Cl ...
最新文章
- 用Auto-TensorCore代码生成优化matmul
- 下拉列表怎么判断html,判断下拉列表中的值,实现页面跳转,请问这个怎么判断?...
- jquery 使用jquery操作Dom
- 涡流探伤仪计算机软件,册亨通过式涡流探伤仪涡流探伤仪保养
- Linux Shell常用技巧(三)
- Activiti中的关于子流程中的并发节点标记处理
- .mod.c 是什么文件
- Stream filter过滤案例
- java并发编程LockSupport讲解
- 【转】在Linux下编译与执行Java程序
- net 中viewstate的原理和使用
- yocto 打包外部应用到 system.img
- 计算机硬件性能指标参考
- this.$message
- EasyUI datagrid editor 中用filebox上传图片失败问题
- MindSpore:自然语言处理(NLP)—分词技术
- 关于CSS的一些语法知识
- 操作系统 --cpu与指令集
- 【概率论与数理统计 第三版 浙江大学 盛骤 谢式千 潘乘毅 编】作业答案
- 设置SeekBar 滑动进度 样式
热门文章
- word小技巧--怎么去掉Word文档封面页码的方法
- 计算机硬盘空间不足怎么删,Win10硬盘空间不足?教你这样清理,瞬间多出10个G!...
- 泰科 | 高压连接革命!CSJ高压连接器与您共赢电动汽车新时代
- mysql学习ppt摘抄笔记
- 隐马尔科夫模型模型:原理、实现
- VMVare中Ubuntu报错:Drag and drop is not supported
- 鸿蒙os正式版推送时间,鸿蒙OS正式版推送时间确定,游戏性能更强,流畅度稳定性均提升...
- c代码实现 ifft运算_二维FFT,IFFT,c语言实现 | 学步园
- Java Jsp+mysql实现企业财务管理系统(普通职工/管理员 员工、公司资产、经营、费用管理)
- 几种下载慢的解决办法