Skip to content

kimloong/platform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

注册中心(服务注册与发现)

启动单一注册中心

java me.kimloong.resource.sample.ResourceSampleApplication

启动多个注册中心

此处为显示效果进行了分行

  • 实例1
java me.kimloong.resource.sample.ResourceSampleApplication
--server.port=8761
--eureka.instance.hostname=registry1.kimloong.me
--eureka.client.register-with-eureka=true
--eureka.client.fetch-registry=true
--eureka.client.service-url.defaultZone=http://registry2.kimloong.me:8762/eureka/
  • 实例2
java me.kimloong.resource.sample.ResourceSampleApplication
--server.port=8762
--eureka.instance.hostname=registry2.kimloong.me
--eureka.client.register-with-eureka=true
--eureka.client.fetch-registry=true
--eureka.client.service-url.defaultZone=http://registry1.kimloong.me:8761/eureka/
  • 实例3
java me.kimloong.resource.sample.ResourceSampleApplication
--server.port=8763
--eureka.instance.hostname=registry3.kimloong.me
--eureka.client.register-with-eureka=true
--eureka.client.fetch-registry=true
--eureka.client.service-url.defaultZone=http://registry1.kimloong.me:8761/eureka/

配置中心

用户账号认证(UAA:User Account and Authentication)

如何运行本项目

  1. 启动arangodb
sudo docker run -p 8529:8529 -e ARANGO_ROOT_PASSWORD=root --name user-center-db -d arangodb
  1. 访问arangodb
http://localhost:8529
  1. 启动服务
  • 使用maven执行spring-boot:run
  1. 注册用户
[POST] http://localhost:8080/uc/users
Header:
  无
Body:
  {
    "username":"user",
    "password":"123456"
  }
  1. 在浏览器请求以下链接(以下链接为模拟第三方客户端登录)
http://localhost:5000/oauth/authorize?response_type=code&client_id=microblog-client&redirect_uri=http://localhost:8082/microblog-client

请求会跳转至登录页面,输入用户名密码(步骤4注册的用户),请求会再次跳转至

http://localhost:8082/microblog-client?code=I5l6xR

复制跳转链接中的code(即这里的I5l6xR

  1. 获取token
[POST] http://localhost:8080/uc/oauth/token?grant_type=authorization_code&redirect_uri=http://localhost:8082/microblog-client&code=I5l6xR
Header:
  Authorization:Basic bWljcm9ibG9nLWNsaWVudDpzZWNyZXQxMjM=
Body:
  无

Header里的AuthorizationclientId:clientSecret进行Base加密得来的,可以到这里 响应如下:

{
  "access_token": "f5970310-ed94-4c0f-8acb-809fe0e626c8",
  "token_type": "bearer",
  "expires_in": 43199,
  "scope": "read"
}
  1. Resource Server请求 我们从上一步中得到了access_token就可以使用它来请求资源服务器,这里以microblog项目为例
[GET] http://localhost:8081/microblog/hello
Header:
  Authorization Bearer f5970310-ed94-4c0f-8acb-809fe0e626c8

解决问题

1. 使用Bearer Token访问UAA无法认证通过而跳转至登录页面

  • 问题描述 Spring Boot1.4.x升级到1.5.x时,请求的Bearer Token无法被正确解析

  • 问题原因 升级后,WebSecurityConfigconfig方法变成在ResourceServerConfigconfig方法之前执行,导致FilterChainProxyfilters顺序发生改变,请求被WebSecurityConfig注册的Filter处理了,而处理Bearer TokenOAuth2AuthenticationProcessingFilter则是由ResourceServerConfig注册,未能被正确执行

  • 解决方案 在配置文件中指定security.oauth2.resource.filter-order: 1

  • 参考

migrating SpringBoot 1.4.4 to 1.5.1 cause oauth2 NullPointerException on ResourceServer

2. Client接入,登录验证成功携带code返回Client时,报401 Unauthorized

  • 问题描述 Client控制台报错信息
There was an unexpected error (type=Unauthorized, status=401).
Authentication Failed: Could not obtain access token
.....
Possible CSRF detected - state parameter was present but no state could be found
  • 问题原因 通过源码跟踪,发现登录验证成功后在类AuthorizationCodeAccessTokenProvider获取preservedState为空而抛出了异常,猜可能跟cookie同源机制有关

  • 解决方案 将Authorization ServerClientContext Path设置成不一样即可,在两者不同host时,则不会有问题。

  • 参考

Unable to get EnableOauth2Sso Working — BadCredentialsException: Could not obtain access token

3. 登录验证成功且请求完access token后(/oauth/check_token阶段)报错

  • 问题描述 报Client500 Internal Server ErrorServer403 Forbidden

  • 问题原因 Server端的/oauth/check_token默认为denyAll(),所以无法进请求成功

  • 解决方案

public class OAuth2ProviderConfig extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients()
                .checkTokenAccess("fullyAuthenticated");
    }
}
  • 参考

How to use RemoteTokenService?

4. 使用Bearer Token访问Resource Serverinsufficient scope for this resource

  • 问题描述 在Resource ServerResourceServerConfig配置了如下权限控制
@Override
public void configure(HttpSecurity http) throws Exception {

    http.antMatcher("/**")
            .authorizeRequests()
            .anyRequest().access("#oauth2.hasScope('read')");
}

同时使用UserInfoTokenServices进行Token验证

@Bean
public ResourceServerTokenServices tokenService() {
    return new UserInfoTokenServices(
            resourceServerProperties.getUserInfoUri(),
            resourceServerProperties.getClientId());
}
  • 问题原因 该报错为Resource Server端的报错,实际UAA已经完成了Token的验证并返回了Principal,UserInfoTokenServices仅作为获取用户信息,所以对与Resource Server端来讲,这是一个认证用户,而无法使用scope来进行权限验证。如果想验证scope

  • 解决方案

  1. 改用RemoteTokenServices,配置security.oauth2.resource.token-info-uri; 因为ResourceServerTokenServicesConfiguration已有注册一个RemoteTokenServices因此可以直接省略; 实际user-info-uritoken-info-uri都有返回scope

  2. 使用hasRole('USER')验证是登录用户

@Override
public void configure(HttpSecurity http) throws Exception {

    http.antMatcher("/**")
            .authorizeRequests()
            .anyRequest().access("hasRole('USER')");
}
  1. 依旧使用#oauth2.hasScope('read'),重写UserInfoTokenServices,查阅参考中的评论
  • 参考

#oauth2.hasScope and Resource Server

参考文档

Spring REST API + OAuth2 + AngularJS

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published