java中的接口是类吗
291
2023-02-14
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。
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.
@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
@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 安全配置
@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 配置
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:euFjwqjH5432/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服务配置
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter{
@OverrideuFjwqjHe
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的地址即可:
security:
oauth2:
resource:
id: order-service
user-info-uri: http://localhost:8080/uaa/user
prefer-token-info: false
3.3 权限测试控制器
具备authority未query-demo的才能访问,即为admin用户
@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支持
@Configuration
@EnableOAuth2Sso
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
4.2 配置
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
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
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~