spring cloud oauth2.0 鉴权
标签(空格分隔): springcloud oauth 鉴权
[TOC]
1.概述
文章主要是描述 springcloud 的一个鉴权,利用 oauth2.0 和 security 实现,所以也继承了 security 的权限框架,粒度可以达到按钮级别,具体还是要看设计思路
这里会介绍 3 种的 token 存储方式,(基于内存,基于 redis,基于 jwt)
还有两种 client 的配置方式,一种是采用官方数据库进行初始化,另一种是写在代码内存中。
2.实现流程
在这简单的说一下,不说的那么复杂。一个注册中心,一个鉴权的服务(我暂时把用户也放在鉴权服务里了,你若是喜欢也可以单独分出去),一个 A 服务(就几个简单的 controller 接口)。
项目启动后,用户通过/oauth/token 获取到 access_token,然后通过 access_token 可以请求具体接口,在资源服务器(也就是 A 服务)的配置文件中可以加入一个获取用户信息的配置项,这样就可以把用户信息获取得到,进行权限的判断。
暂时没有用网关去做 oauth2.0 的统一验证,我觉得网关还是只做转发路由,具体还是看情况吧。
3.代码实现
3.1 注册中心 eureka
这个没什么好说的,我用的是 springboot2.0.4 版本,cloud 版本为 Finchley.RELEASE
server: port : 8761 eureka: instance: hostname : localhost client: registerWithEureka : false fetchRegistry : false serviceUrl: defaultZone : http://${eureka.instance.hostname}:${server.port}/eureka/
3.2 资源服务器
配置文件
spring:
application:
name: oauth-a
mvc:
servlet:
load-on-startup: 1 #初始化加载,不用懒加载
server:
port: 8888
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/
registry-fetch-interval-seconds: 5
instance:
lease-expiration-duration-in-seconds: 15
lease-renewal-interval-in-seconds: 5
prefer-ip-address: true
instance-id: ${spring.application.name}:${server.port}
logging:
level:
root: info
security:
oauth2:
resource:
user-info-uri: http://127.0.0.1:7777/user/user-me
prefer-token-info: false
主要是看后面一段 security 配置
配置了一个资源访问的地址,通过这个接口可以获取到登录的用户信息,而这个用户里面的信息包含的内容,要看你在登录的时候设置了什么了,具体看下面的鉴权的服务,一般会在里面返回所有角色信息和权限信息,在security的权限框架中,没有把角色和权限分开,都是统一用的一个集合,所以在角色里要默认加一个ROLE的前缀,如(ROLE_ADMIN,ROLE_USER)
。
security.oauth2.resource.user-info-uri:配置userinfo的url地址 security.oauth2.resource.token-info-uri:配置check-token的url地址; security.oauth2.resource.prefer-token-info=true,如果上面两个都配置了,更倾向于用哪个
然后我们看一下主要的资源服务器配置:
ResourceServerConfig.java
package com.example.oautha.config;
import java.util.HashMap;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* 资源服务配置
*
*/
@EnableResourceServer
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@SuppressWarnings({ "unchecked", "rawtypes", "serial" })
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().exceptionHandling()
.authenticationEntryPoint((req, resp, exception) -> {
resp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
resp.getWriter().write(new ObjectMapper().writeValueAsString(new HashMap() {{
put("status", 0);
put("error", "没有权限");
}}));
})
.and().authorizeRequests()
.antMatchers("/anon/**").permitAll() // 放开权限的url
.anyRequest().authenticated().and().httpBasic();
http.headers().frameOptions().sameOrigin();
}
}
中间有一个自定义的返回信息设置,看大家喜好,也可以不要。
然后是上面有一个注解 @EnableGlobalMethodSecurity(prePostEnabled = true)
,开启这个注解为 true,才可以使用 security 的权限控制。如下面的 controller
TestController.java
package com.example.oautha.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@RequestMapping("/anon/test")
public String anon(String param) {
return "/anon/test:"+param;
}
@RequestMapping("/auth/test")
public String auth(String param) {
return "/auth/test:"+param;
}
@RequestMapping("/auth/test1")
@PreAuthorize("hasRole('ROLE_USER')")
public String auth1(String param) {
return "/auth/test1";
}
@RequestMapping("/auth/test2")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String auth2(String param) {
return "/auth/test2";
}
}
@PreAuthorize("hasRole('ROLE_ADMIN')")
注解就可以做到权限的控制,这是判断角色的,还有判断具体权限的,如:
@PreAuthorize("hasAuthority('mail:query')") @PreAuthorize("hasAnyAuthority('back:menu:set2role','menu:byroleid')")
3.3 授权服务器
首先看用户登录这一块:
@Service("userDetailsServiceImpl") public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserDao userDao; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userDao.findByUsername(username); if (user == null) { throw new AuthenticationCredentialsNotFoundException("用户不存在"); } return user; } }
这是重写了框架自带的一个加载方法,密码校验框架底层做了判断,哦我们只要把信息输入进去就行,而角色和权限信息在此时也需要设置进去,在这里的 User 类是实现了 UserDetails 接口的,如:
@Data public class User implements UserDetails{ /** * */ private static final long serialVersionUID = 1L; private Long id; private String username; private String password; @Override public Collection<? extends GrantedAuthority> getAuthorities() { //默认给一个用户角色,生产环境自己添加相应的角色和权限 return AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"); } @Override public boolean isAccountNonExpired() { //判断用户是否过期,默认为true,生产环境视情况修改,赋值 return true; } @Override public boolean isAccountNonLocked() { //判断用户是否被锁定,默认为true,生产环境视情况修改,赋值 return true; } @Override public boolean isCredentialsNonExpired() { //判断用户凭证是否过期,默认为true,生产环境视情况修改,赋值 return true; } @Override public boolean isEnabled() { //判断用户是否启用,默认为true,生产环境视情况修改,赋值 return true; } }
然后我们看最重要的授权配置
3.3.1 内存存储
package com.example.user.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
/**
* 授权服务器配置
*
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigInMemory extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Autowired
public BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
public UserDetailsService userDetailsServiceImpl;
/**
* 配置token的数据源、自定义的tokenServices等信息
* 配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory
*
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(new InMemoryTokenStore())
.userDetailsService(userDetailsServiceImpl);
}
/**
* 配置安全策略
* 对应于配置AuthorizationServer安全认证的相关信息,创建ClientCredentialsTokenEndpointFilter核心过滤器
*
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients();//允许表单提交client信息
security.tokenKeyAccess("permitAll()");
security.checkTokenAccess("isAuthenticated()");//allow check token
}
/**
* 配置客户端认证信息
* 配置OAuth2的客户端相关信息,client信息包括:clientId、secret、scope、authorizedGrantTypes
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//基于oauth_client_token表的操作
clients.withClientDetails(new JdbcClientDetailsService(dataSource));
//基于内存
/*clients.inMemory().withClient("system") // client_id
.secret(bCryptPasswordEncoder.encode("system")) // client_secret
.authorizedGrantTypes("authorization_code", "password") // 该client允许的授权类型
.scopes("app"); // 允许的授权范围
*/
}
}
3.3.2jwt 存储
package com.example.user.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
/**
* 授权服务器配置
*
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigJwt extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Autowired
public BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
public UserDetailsService userDetailsServiceImpl;
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
/* KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("test-jwt.jks"), "test123".toCharArray());
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("test-jwt"));
return converter;*/
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
// JWT签名
converter.setSigningKey("0123456789");
return converter;
}
/**
* 配置token的数据源、自定义的tokenServices等信息
* 配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory
*
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore())
.accessTokenConverter(jwtAccessTokenConverter())
.userDetailsService(userDetailsServiceImpl);
}
/**
* 配置安全策略
* 对应于配置AuthorizationServer安全认证的相关信息,创建ClientCredentialsTokenEndpointFilter核心过滤器
*
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients();//允许表单提交client信息
security.tokenKeyAccess("permitAll()");
security.checkTokenAccess("isAuthenticated()");//allow check token
}
/**
* 配置客户端认证信息
* 配置OAuth2的客户端相关信息,client信息包括:clientId、secret、scope、authorizedGrantTypes
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//基于oauth_client_token表的操作
clients.withClientDetails(new JdbcClientDetailsService(dataSource));
//基于内存
/*clients.inMemory().withClient("system") // client_id
.secret(bCryptPasswordEncoder.encode("system")) // client_secret
.authorizedGrantTypes("authorization_code", "password") // 该client允许的授权类型
.scopes("app"); // 允许的授权范围
*/
}
}
3.3.3redis 存储
package com.example.user.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
/**
* 授权服务器配置
*
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigRedis extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Autowired
public BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
public UserDetailsService userDetailsServiceImpl;
@Bean
public TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
/**
* 配置token的数据源、自定义的tokenServices等信息
* 配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory
*
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore())
.userDetailsService(userDetailsServiceImpl);
}
/**
* 配置安全策略
* 对应于配置AuthorizationServer安全认证的相关信息,创建ClientCredentialsTokenEndpointFilter核心过滤器
*
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients();//允许表单提交client信息
security.tokenKeyAccess("permitAll()");
security.checkTokenAccess("isAuthenticated()");//allow check token
}
/**
* 配置客户端认证信息
* 配置OAuth2的客户端相关信息,client信息包括:clientId、secret、scope、authorizedGrantTypes
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//基于oauth_client_token表的操作
clients.withClientDetails(new JdbcClientDetailsService(dataSource));
//基于内存
/*clients.inMemory().withClient("system") // client_id
.secret(bCryptPasswordEncoder.encode("system")) // client_secret
.authorizedGrantTypes("authorization_code", "password") // 该client允许的授权类型
.scopes("app"); // 允许的授权范围
*/
}
}
其实我们可以看出,主要的不同就是在于 AuthorizationServerEndpointsConfigurer endpoints
的配置不同,这里是用来配置 token 的数据源、自定义的 tokenServices 等信息,也就是对令牌存储,认证的。而 AuthorizationServerSecurityConfigurer security
的安全认证比较简单,授权一下表单提交和 token 认证即可,
再是 client 的 ClientDetailsServiceConfigurer clients
配置信息,
一种是官方自带的一个数据库 oauth_client_token,一种是写在内存中,可以放在配置文件中读取。
接着我们看一下授权服务器的资源配置,因为在授权服务器也会存在一些需要获取的资源,所以也需要一些简单的配置,以及安全认证也是一样,如下两个类:
ResourceServerConfig.java
package com.example.user.config;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* 资源服务配置<br>
*
* 注解@EnableResourceServer帮我们加入了org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter<br>
* 该filter帮我们从request里解析出access_token<br>
* 并通过org.springframework.security.oauth2.provider.token.DefaultTokenServices根据access_token和认证服务器配置里的TokenStore从redis或者jwt里解析出用户
*
* 注意认证中心的@EnableResourceServer和别的微服务里的@EnableResourceServer有些不同<br>
* 别的微服务是通过org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices来获取用户的
*
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@SuppressWarnings("serial")
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new OAuth2RequestedMatcher()).csrf().disable().exceptionHandling()
.authenticationEntryPoint((req, resp, exception) -> {
resp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
resp.getWriter().write(new ObjectMapper().writeValueAsString(new HashMap<String, String>() {
{
put("status", "401");
put("error", "ResourceServerConfigurerAdapter认证失败");
}
}));
}).and().authorizeRequests().antMatchers().permitAll().anyRequest().authenticated();
}
/**
* 判断来源请求是否包含oauth2授权信息<br>
* url参数中含有access_token,或者header里有Authorization
*/
private static class OAuth2RequestedMatcher implements RequestMatcher {
@Override
public boolean matches(HttpServletRequest request) {
// 请求参数中包含access_token参数
if (request.getParameter(OAuth2AccessToken.ACCESS_TOKEN) != null) {
return true;
}
// 头部的Authorization值以Bearer开头
String auth = request.getHeader("Authorization");
if (auth != null) {
return auth.startsWith(OAuth2AccessToken.BEARER_TYPE);
}
return false;
}
}
}
SecurityConfig.java
package com.example.user.config;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* spring security配置
*
*/
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public UserDetailsService userDetailsServiceImpl;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* http安全配置
*
* @param http
* @throws Exception
*/
@SuppressWarnings("serial")
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().csrf().disable().exceptionHandling().authenticationEntryPoint((req, resp, exception) -> {
resp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
resp.getWriter().write(new ObjectMapper().writeValueAsString(new HashMap<String, String>(2) {
{
put("status", "401");
put("error", "WebSecurityConfigurerAdapter认证失败");
}
}));
}).and().authorizeRequests().antMatchers().permitAll().anyRequest().authenticated();
}
}
这里没有太多的描述,相比于文字,我还是更喜欢直接代码运行跑起来后,一边看运行情况,一边了解原理,看自己的学习方式而定吧。
然后看一下 controller,这里有一个前面配置文件中请求的接口信息,就是获取用户的信息,检验 token 的那个
package com.example.user.controller;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.user.model.User;
import com.example.user.service.UserService;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/findByUsername")
public User findByUsername(String username) {
return userService.findByUsername(username);
}
@GetMapping("/user-me")
public Principal user(Principal member) {
//获取当前用户信息
return member;
}
@RequestMapping("/auth/test")
public String auth(String param) {
return "/auth/test:"+param;
}
@RequestMapping("/auth/test1")
@PreAuthorize("hasRole('ROLE_USER')")
public String auth1(String param) {
return "/auth/test1";
}
@RequestMapping("/auth/test2")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String auth2(String param) {
return "/auth/test2";
}
}
主要看这里
@GetMapping("/user-me") public Principal user(Principal member) { //获取当前用户信息 return member; }
4.演示效果
这里我用的是 postman 模拟请求
4.1 请求授权服务
1.请求 token
2.刷新 token
4.2 请求 A 服务
1.请求 anon 公开接口
2.请求 test2 接口(拥有 admin 角色才可以)
2.请求 test1 接口(拥有 user 角色才可以)
5.添加 zuul 网关
zuul 网关最好的就是只做路由,具体的权限还是由各自的资源服务器处理,个人理解,不喜勿喷
@Configuration @EnableOAuth2Sso public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); } }
spring: application: name: oauth-zuul server: port: 9030 eureka: instance: prefer-ip-address: true #使用IP注册 instance-id: ${spring.application.name}:${server.port} client: service-url: defaultZone: http://localhost:8761/eureka/ zuul: host: connect-timeout-millis: 10000 socket-timeout-millis: 60000 routes: oauth-center: path: /uaa/** strip-prefix: true sensitiveHeaders: serviceId: oauth-center oauth-a: path: /oa/** strip-prefix: true sensitiveHeaders: serviceId: oauth-a security: oauth2: client: access-token-uri: http://localhost:9030/uaa/oauth/token ##网关的地址 user-authorization-uri: http://localhost:9030/uaa/oauth/authorize #client-id: system #OAuth2客户端ID #client-secret: system #OAuth2客户端密钥 resource: user-info-uri: http://localhost:9030/uaa/user/user-me prefer-token-info: false #jwt: #key-value: 0123456789 #使
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于