OAuth2开发指导:https://projects.spring.io/spring-security-oauth/docs/oauth2.html Spring Boot下的OAuth2使用:https://docs.spring.io/spring-security-oauth2-boot/docs/2.2.0.RELEASE/reference/html5/ Spring Cloud Security: 博客参考1:http://www.javashuo.com/article/p-kdetiktk-de.htmlhtml
当前版本是:Spring Boot2.2.0.RELEASE,Spring Cloud Hoxton.M3 因为Spring Security OAuth2并不在Spring Boot中维护,因此不能在Spring Boot中自动引入依赖 可是Spring Cloud中好像维护了Spring Security OAuth2的版本 生成的工程自动引入了spring-cloud-starter-oauth2依赖,该依赖中包含了spring-security-oauth2-autoconfigure依赖 手动加入spring-security-oauth2-autoconfigure依赖前端
增长@EnableAuthorizationServer注解html5
@EnableAuthorizationServer @SpringBootApplication public class SimpleAuthorizationServerApplication { public static void main(String[] args) { SpringApplication.run(SimpleAuthorizationServerApplication, args); } }
security: oauth2: client: client-id: first-client client-secret: noonewilleverguess
获取token: curl client:pwd@localhost:8080/oauth/token -d grant_type=client_credentials -d scope=anyjava
@Configuration public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { // 配置客户端明细 @SneakyThrows @Override public void configure(ClientDetailsServiceConfigurer clients) { // 一、基于内存的客户端明细 clients.inMemory().withClient("client")// 容许访问的客户端 .secret("{noop}pwd")// 密码 .authorizedGrantTypes("refresh_token", "password", "client_credentials")// 容许的受权类型 .scopes("webclient", "mobileclient");// 引用程序做用域 } }
而后经过客户端密码模式获取token curl client:pwd@localhost:8080/oauth/token -d grant_type=client_credentials -d scope=webclient 注意,新版本的Spring Security5中,密码增长了前缀{noop},能够指定密码的加密内容,只有服务端须要加该前缀,前端传的是加密后的密码mysql
修改自定义实现获取客户端明细 分别引入jdbc、mysql、druid依赖,这里借助了JdbcClientDetailsService这个实现,进行了扩展,稍微修改了SQL,以及加入了缓存机制 注意一点:这里的sql中,使用了CONCAT('{noop}',client_secret),表明这里的密码是明文存储的,之后有须要能够修改这里 再次经过客户端密码模式获取token,客户端帐号密码、scope,按数据库存储的输入,便可获取获得 curl client:pwd@localhost:8080/oauth/token -d grant_type=client_credentials -d scope=webclientweb
参考https://docs.spring.io/spring-security-oauth2-boot/docs/2.2.0.RELEASE/reference/html5/#oauth2-boot-authorization-server-password-grant-authentication-configuration 要使用OAuth2的Password模式,有多种方式,因为咱们使用AuthorizationServerConfigurerAdapter,符合1.7.3所说,以下便可实现spring
@Configuration public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationConfiguration authenticationConfiguration; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationConfiguration.getAuthenticationManager()) } }
@Service public class HopeUserDetailsService implements UserDetailsService { @Override @SneakyThrows public UserDetails loadUserByUsername(String username) { Collection<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("role1"); return new HopeUser(1, 1, 1, "hope", "{noop}hope", true, true, true, true,authorities ); } }
curl client:pwd@localhost:8080/oauth/token -d grant_type=password -d scope=webclient -d username=hope -d password=hope 便可获取到tokensql
默认验证token端点是/oauth/check_token 先配置验证端点彻底开放数据库
@Configuration public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) { oauthServer .checkTokenAccess("permitAll()"); } }
curl client:pwd@localhost:8080/oauth/check_token -d token=8313a24b-c0d2-437b-afb0-0bb4fd440f47 返回令牌中携带信息缓存
使用Spring Boot初始化项目工具,勾选Web 手动加入spring-security-oauth2-autoconfigure依赖 使用@EnableResourceServer注解 配置文件以下
security: oauth2: resource: token-info-uri: http://localhost:8080/oauth/check_token client: # 配置后才能认证,生产环境建议设置独立的客户端信息 client-id: test client-secret: test scope: server
注意,须要开放受权服务器的check_token端点
@Configuration public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) { oauthServer .checkTokenAccess("isAuthenticated()"); } }
此时,直接访问资源提示没有权限 访问受权服务器,获取token,使用bear token访问这个受保护资源,访问成功!
spring-security-oauth2-autoconfigure已包含jwt依赖,因此不须要处理依赖 受权服务器: 经过AuthorizationServerEndpointsConfigurer配置.accessTokenConverter(jwtAccessTokenConverter),配置一个JwtAccessTokenConverter便可,具体方法下面讨论 资源服务器: 配置application配置文件便可。
2者成组配置:
方式1:对称加密 受权服务器:
@Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey("micosrv_signing_key"); return converter; }
资源服务器:
security: oauth2: resource: jwt: key-value: micosrv_signing_key
方式2:非对称加密(自行赋值) 受权服务器:
config: oauth2: # openssl genrsa -out jwt.pem 2048 # openssl rsa -in jwt.pem privateKey: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAm4irSNcR7CSSfXconxL4g4M4j34wTWdTv93ocMn4VmdB7rCB U/BlxXtBUf/cgLIgQhQrAPszSZSmxiEXCOkGPr4aQBQuPgmNIR95Dhbzw/ZN0Bne cAt3ZfkkDBHv8kH3kR/jYGTdwrxKeDgXGljNsTRhbjuASxPG/Z6gU1yRPCsgc2r8 NYnztWGcDWqaobqjG3/yzFmusoAboyV7asIpo4yk378LmonDNwxnOOTb2Peg5Pee lwfOwJPbftK1VOOt18zA0cchw6dHUzq9NlB8clps/VdBap9BxU3/0YoFXRIc18ny zrWo2BcY2KQqX//AJC3OAfrfDmo+BGK8E0mp8wIDAQABAoIBAENp64P45GXMPEpx eYPpfxnRqJRZh6olHSHOl087243n16YTjxrI2fPMxrU6B2Mo0d6SS0lzl/lOmzLJ aOiNyA0t7MbVeG2fSjKPJ7M5s5K+kV+fttAtyCTE5iDtLWl9ukaG4dEIJy6e2lBd T3Y2A4HJSGm1FJh2DAwl0ywOtUy0X6ki9DgXVAaCGDuoU25Rhun64dh802DZbEEJ LdorIyeJ0ovCZyNvhlZRYkAOPy3k88smYl2jE/AbZ7pCKz/XggDcjNsERm2llaa3 pNTAZQUlHu0BQrCn6J9BxtMPyduiyrE+JYqTwnYhWQ5QRe/2J8O3t0eIK9TfUQpJ DrZf00ECgYEAy/sLX8UCmERwMuaQSwoM0BHTZIc0iAsgiXbVOLua9I3Tu/mXOVdH TikjdoWLqM62bA9dN/oqzHDwvqCy6zwamjFVSmJUejf5v+52Qj64leOmDX/RC4ne L08N1nP/Y4X24Y/5zq18qvVlhOMDdydzayJFrGhkQKhJg58pRUIdenECgYEAwzLC Awr3LeUlHa+d2O6siJVmljTc8lT+qX4TvqTDH8rAC/EyKMNaTjaX6mWosZZ7qYXv EMxvQzTEzUHRXrCGlhbX8xiBlWnvpghF2GJEvP9WaU/+OCr0gItRSLPDuZ6ctzKb 3QkBEiC8ODyPRKzlA67D23S3KJB067IUV81h9KMCgYBXUqmT3is2NFYz9DBhb3P8 vyTYLGl4tArBznWJTAcSGoVCO59ZlNuZwlLEMnePVK8To6AsjpQz4UWu1ezCd4CL 8gKpTV8M01m/qL5HrcInqMU1kjpTzjmn1xf9brsuR/NgrNoseGieZ1+GfAjHwcPP YWSiYi5I38JY7pIkbCFigQKBgAnVtty8YrPXRcV3IbbaX6sKC/8pbrBvA926Unha iNJDPuXbIzHWleg26/SNZrB76oMiEmeARWLXd8r3s/rXXhCV2g+PfofurHprFEnQ ubHkE5B+zUo7L9KCMng9RnFFwpOgYyYB3CHzsEgNFRLauzcySP/3o3rRvHJbqJa7 7GGNAoGBAKSBn4zq0iNWI2BUBb90icMsHEneiydGtFcEl3/Sz8vmjFZn0sjRbGoY gmP9LlQ+o7xRiJ/LTesi5BA6zCGrcdp0aeyJzCRbFc3WqjGeyLbfx1sJVVB6PnvS iKvvCOJq6kl3/opO+ybqJ8dzkEyoj8K4+fcX1+U6eW2w+vSpOosG -----END RSA PRIVATE KEY----- # openssl rsa -in jwt.pem -pubout publicKey: | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm4irSNcR7CSSfXconxL4 g4M4j34wTWdTv93ocMn4VmdB7rCBU/BlxXtBUf/cgLIgQhQrAPszSZSmxiEXCOkG Pr4aQBQuPgmNIR95Dhbzw/ZN0BnecAt3ZfkkDBHv8kH3kR/jYGTdwrxKeDgXGljN sTRhbjuASxPG/Z6gU1yRPCsgc2r8NYnztWGcDWqaobqjG3/yzFmusoAboyV7asIp o4yk378LmonDNwxnOOTb2Peg5PeelwfOwJPbftK1VOOt18zA0cchw6dHUzq9NlB8 clps/VdBap9BxU3/0YoFXRIc18nyzrWo2BcY2KQqX//AJC3OAfrfDmo+BGK8E0mp 8wIDAQAB -----END PUBLIC KEY-----
@Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { // 自行生成公私钥 JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(privateKey); converter.setVerifierKey(publicKey); return converter; }
资源服务器:
security: oauth2: resource: jwt: key-value: -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm4irSNcR7CSSfXconxL4 g4M4j34wTWdTv93ocMn4VmdB7rCBU/BlxXtBUf/cgLIgQhQrAPszSZSmxiEXCOkG Pr4aQBQuPgmNIR95Dhbzw/ZN0BnecAt3ZfkkDBHv8kH3kR/jYGTdwrxKeDgXGljN sTRhbjuASxPG/Z6gU1yRPCsgc2r8NYnztWGcDWqaobqjG3/yzFmusoAboyV7asIp o4yk378LmonDNwxnOOTb2Peg5PeelwfOwJPbftK1VOOt18zA0cchw6dHUzq9NlB8 clps/VdBap9BxU3/0YoFXRIc18nyzrWo2BcY2KQqX//AJC3OAfrfDmo+BGK8E0mp 8wIDAQAB -----END PUBLIC KEY-----
方式3:非对称加密(经过token_key端点) 受权服务器: 在方式2的基础上,须要配置开放token_key端口,在AuthorizationServerConfigurerAdapter中配置
@Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) { oauthServer.tokenKeyAccess("permitAll()"); }
资源服务器:
security: oauth2: resource: jwt: key-uri: http://localhost:8080/oauth/token_key
客户端添加依赖:alibaba discovery,alibaba config,hystricx断路器,feign依赖,spring-cloud-starter-security 而且管理版本:spring-cloud-alibaba-dependencies 0.9.0.RELEASE 使用@SpringCloudApplication注解,开启Cloud App,支持服务注册于发现和断路器 使用@EnableFeignClients注解,支持Feign客户端 配置一个OAuth2FeignRequestInterceptor拦截器,经过AccessTokenContextRelay来传递token AccessTokenContextRelay在@EnableOAuth2Client中有配置,可是咱们这里不做为一个OAuth2客户端来看,能够本身建立一个AccessTokenContextRelay 调用Feign,便可看到token是否能正常传递
使用原来的令牌,在资源服务端访问受权服务器的时候,进行缓存,下次访问的时候取缓存 参考文章: 冷总:https://cloud.tencent.com/developer/article/1435727 冷总:https://my.oschina.net/giegie/blog/3023768 http://www.javashuo.com/article/p-ecugkcoa-ke.html 思路
pig中应该是网关进行了加密和解密,OAuth2服务器接收的应该是原生密码,而后经过BCRYPT加密,与数据库中已通过BCRYPT加密的密码进行对比
返回值是经过AccessTokenConverter来进行转换的,我继承DefaultAccessTokenConverter,并在convertAccessToken中,增长自定义的信息 受权服务器:在AuthorizationServerConfigurerAdapter中注入AccessTokenConverter 资源服务器:在ResourceServerTokenServices中注入AccessTokenConverter