https://www.jb51.net/article/136129.htm
这篇文章主要介绍了Spring Cloud下基于OAUTH2认证授权的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
在Spring Cloud
需要使用OAUTH2
来实现多个微服务的统一认证授权,通过向OAUTH服务
发送某个类型的grant type
进行集中认证和授权,从而获得access_token
,而这个token是受其他微服务信任的,我们在后续的访问可以通过access_token
来进行,从而实现了微服务的统一认证授权。
本示例提供了四大部分:
discovery-service
:服务注册和发现的基本模块auth-server
:OAUTH2认证授权中心order-service
:普通微服务,用来验证认证和授权api-gateway
:边界网关(所有微服务都在它之后)
OAUTH2中的角色:
Resource Server
:被授权访问的资源Authotization Server
:OAUTH2认证授权中心Resource Owner
: 用户Client
:使用API的客户端(如Android 、IOS、web app)
Grant Type:
Authorization Code
:用在服务端应用之间Implicit
:用在移动app或者web app(这些app是在用户的设备上的,如在手机上调起微信来进行认证授权)Resource Owner Password Credentials(password)
:应用直接都是受信任的(都是由一家公司开发的,本例子使用Client Credentials
:用在应用API访问。
1.基础环境
使用Postgres
作为账户存储,Redis
作为Token
存储,使用docker-compose
在服务器上启动Postgres
和Redis
。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Redis: image: sameersbn/redis:latest ports: - "6379:6379" volumes: - /srv/docker/redis:/var/lib/redis:Z restart: always PostgreSQL: restart: always image: sameersbn/postgresql:9.6-2 ports: - "5432:5432" environment: - DEBUG=false - DB_USER=wang - DB_PASS=yunfei - DB_NAME=order volumes: - /srv/docker/postgresql:/var/lib/postgresql:Z |
2.auth-server
2.1 OAuth2服务配置
Redis
用来存储token
,服务重启后,无需重新获取token
.
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private RedisConnectionFactory connectionFactory; @Bean public RedisTokenStore tokenStore() { return new RedisTokenStore(connectionFactory); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .authenticationManager(authenticationManager) .tokenStore(tokenStore()); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security .tokenKeyAccess( "permitAll()" ) .checkTokenAccess( "isAuthenticated()" ); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient( "android" ) .scopes( "xx" ) //此处的scopes是无用的,可以随意设置 .secret( "android" ) .authorizedGrantTypes( "password" , "authorization_code" , "refresh_token" ) .and() .withClient( "webapp" ) .scopes( "xx" ) .authorizedGrantTypes( "implicit" ); } } |
2.2 Resource服务配置
auth-server
提供user信息,所以auth-server
也是一个Resource Server
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .csrf().disable() .exceptionHandling() .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED)) .and() .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic(); } } |
?
1 2 3 4 5 6 7 8 | @RestController public class UserController { @GetMapping ( "/user" ) public Principal user(Principal user){ return user; } } |
2.3 安全配置
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public UserDetailsService userDetailsService(){ return new DomainUserDetailsService(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userDetailsService()) .passwordEncoder(passwordEncoder()); } @Bean public SecurityEvaluationContextExtension securityEvaluationContextExtension() { return new SecurityEvaluationContextExtension(); } //不定义没有password grant_type @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super .authenticationManagerBean(); } } |
2.4 权限设计
采用用户(SysUser)
角色(SysRole)
权限(SysAuthotity)
设置,彼此之间的关系是多对多
。通过DomainUserDetailsService
加载用户和权限。
2.5 配置
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | spring: profiles: active: ${SPRING_PROFILES_ACTIVE:dev} application: name: auth-server jpa: open-in-view: true database: POSTGRESQL show-sql: true hibernate: ddl-auto: update datasource: platform: postgres url: jdbc:postgresql: //192.168.1.140:5432/auth username: wang password: yunfei driver- class -name: org.postgresql.Driver redis: host: 192.168 . 1.140 server: port: 9999 eureka: client: serviceUrl: defaultZone: http: //${eureka.host:localhost}:${eureka.port:8761}/eureka/ logging.level.org.springframework.security: DEBUG logging.leve.org.springframework: DEBUG ##很重要 security: oauth2: resource: filter-order: 3 |
2.6 测试数据
data.sql
里初始化了两个用户admin
->ROLE_ADMIN
->query_demo
,wyf
->ROLE_USER
3.order-service
3.1 Resource服务配置
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter{ @Override public void configure(HttpSecurity http) throws Exception { http .csrf().disable() .exceptionHandling() .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED)) .and() .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic(); } } |
3.2 用户信息配置
order-service
是一个简单的微服务,使用auth-server
进行认证授权,在它的配置文件指定用户信息在auth-server
的地址即可:
?
3.3 权限测试控制器
具备authority
未query-demo
的才能访问,即为admin
用户
?
1 2 3 4 5 6 7 8 | @RestController public class DemoController { @GetMapping ( "/demo" ) @PreAuthorize ( "hasAuthority('query-demo')" ) public String getDemo(){ return "good" ; } } |
4 api-gateway
api-gateway
在本例中有2个作用:
- 本身作为一个client,使用
implicit
- 作为外部app访问的方向代理
4.1 关闭csrf并开启Oauth2 client支持
?
1 2 3 4 5 6 7 8 9 | @Configuration @EnableOAuth2Sso public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); } } |
4.2 配置
?
5 演示
5.1 客户端调用
使用Postman
向http://localhost:8080/uaa/oauth/token
发送请求获得access_token
(admin用户的如7f9b54d4-fd25-4a2c-a848-ddf8f119230b
)
admin用户
wyf用户
5.2 api-gateway中的webapp调用
暂时没有做测试,下次补充。
6 源码地址
https://github.com/wiselyman/uaa-zuul
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章: