Based OAUTH2 authentication and authorization at Spring Cloud
The Spring Cloud
need to use OAUTH2
a unified authentication and authorization services to implement a plurality of micro through to OAUTH服务
send some type of grant type
centralized authentication and authorization to obtain access_token
, and this token is subject to other micro-service trust, we can follow-up visits access_token
to in order to achieve a unified authentication and authorization micro services.
This example provides four major parts:
eureka
: The basic module service registration and discoveryauth
: OAUTH2 Certification Authorityaccount
: General micro-services, used to verify authentication and authorizationgateway
: Border Gateway (micro services are all behind it)
OAUTH2 roles:
Resource Server
: Is authorized to access resourcesAuthotization Server
: OAUTH2 Certification AuthorityResource Owner
: UserClient
: The client using the API (e.g., Android, IOS, web app)
Grant Type:
authorization_code
:implicit
:password
:refrsh_token
:
1. Basic environment
Use Postgres
as a storage account, Redis
as the Token
storage, use docker-compose
on server startup Postgres
and Redis
.
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 service configuration
Redis
It used to store token
, after the service restarted without re-acquired token
.
@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) .userDetailsService(userDetailsService)//若无,refresh_token会有UserDetailsService is required错误 .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 Service Configuration
auth-server
Provide user information, it auth-server
is also aResource Server
@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(); } }
@RestController public class UserController { @GetMapping("/user") public Principal user(Principal user){ return user; } }
2.3 Security Configuration
@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 Design authority
Using 用户(SysUser)
<-> 角色(SysRole)
<-> 权限(SysAuthotity)
provided, the relationship between each other 多对多
. By DomainUserDetailsService
loading the user and permissions.
2.5 Configuration
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
2.6 Test Data
data.sql
In initializing the two users admin
-> ROLE_ADMIN
-> query_demo
, wyf
->ROLE_USER
3.account
3.1 Resource Service Configuration
@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 User Configuration
account is a simple micro-service, using auth-server
authentication and authorization, specify the user information in its configuration file auth-server
by the address of:
security: oauth2: resource: id: order-service user-info-uri: http://localhost:8080/uaa/user prefer-token-info: false
3.3 Permissions test controller
Have authority
not query-demo
be able to access, that is, admin
the user
@RestController public class DemoController { @GetMapping("/demo") @PreAuthorize("hasAuthority('query-demo')") public String getDemo(){ return "good"; } }
4 api-gateway
api-gateway
There are two roles in this example:
-
Itself as a client, use
implicit
-
Acting as the direction of the external app access
4.1 csrf closed and open Oauth2 client support
@Configuration @EnableOAuth2Sso public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); } }
4.2 Configuration
zuul: routes: uaa: path: /uaa/** sensitiveHeaders: serviceId: auth-server order: path: /order/** sensitiveHeaders: serviceId: order-service add-proxy-headers: true security: oauth2: client: access-token-uri: http://localhost:8080/uaa/oauth/token user-authorization-uri: http://localhost:8080/uaa/oauth/authorize client-id: webapp resource: user-info-uri: http://localhost:8080/uaa/user prefer-token-info: false
Intermodulation between 4.3 Service
feign client without the access token into the request in advance, a need to define OAuth2FeignRequestInterceptor
the bean:
5 demo
5.1 client calls
Using Postman
the http://localhost:8080/uaa/oauth/token
obtained transmission request access_token
(admin user as 7f9b54d4-fd25-4a2c-a848-ddf8f119230b
)
- admin users
webapp calls 5.2 api-gateway in
Temporarily did not do the test, the next supplement.
Open Source Code
Open source code has been hosting to cloud my code:
https://gitee.com/senhelpa-vivo/spring-cloud.git