在application.yml里添加配置
application.yml
oauth2:
client:
id: client
secret: secret
authentication-method: client_secret_basic
grant-types: authorization_code,refresh_token
redirect-uris:
- http://localhost:8081/login/oauth2/code/client
- http://localhost:8081/login/oauth2/code/client2
scopes: openid,user
require-authorization-consent: true
token:
access-token-format: self_contained
access-token-time-to-live: 2h
server:
issuer-uri: http://localhost:9000
创建对应的配置类
如果用lombok没问题的话,可以选择lombok,我用lombok的@Data注解去自动生成getter, setter,idea里没有报错信息,但启动服务时报错,然后我就都给换成自己的写的getter,setter。
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.List;
@Component
@ConfigurationProperties(prefix = "oauth2")
public class OAuth2Properties {
private Client client;
private Token token;
private Server server;
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public Token getToken() {
return token;
}
public void setToken(Token token) {
this.token = token;
}
public Server getServer() {
return server;
}
public void setServer(Server server) {
this.server = server;
}
}
class Client {
private String id;
private String secret;
private String authenticationMethod;
private List<String> grantTypes;
private List<String> redirectUris;
private List<String> scopes;
private boolean requireAuthorizationConsent;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getAuthenticationMethod() {
return authenticationMethod;
}
public void setAuthenticationMethod(String authenticationMethod) {
this.authenticationMethod = authenticationMethod;
}
public List<String> getGrantTypes() {
return grantTypes;
}
public void setGrantTypes(List<String> grantTypes) {
this.grantTypes = grantTypes;
}
public List<String> getRedirectUris() {
return redirectUris;
}
public void setRedirectUris(List<String> redirectUris) {
this.redirectUris = redirectUris;
}
public List<String> getScopes() {
return scopes;
}
public void setScopes(List<String> scopes) {
this.scopes = scopes;
}
public boolean isRequireAuthorizationConsent() {
return requireAuthorizationConsent;
}
public void setRequireAuthorizationConsent(boolean requireAuthorizationConsent) {
this.requireAuthorizationConsent = requireAuthorizationConsent;
}
}
class Token {
private String accessTokenFormat;
private Duration accessTokenTimeToLive;
public String getAccessTokenFormat() {
return accessTokenFormat;
}
public void setAccessTokenFormat(String accessTokenFormat) {
this.accessTokenFormat = accessTokenFormat;
}
public Duration getAccessTokenTimeToLive() {
return accessTokenTimeToLive;
}
public void setAccessTokenTimeToLive(Duration accessTokenTimeToLive) {
this.accessTokenTimeToLive = accessTokenTimeToLive;
}
}
class Server {
private String issuerUri;
public String getIssuerUri() {
return issuerUri;
}
public void setIssuerUri(String issuerUri) {
this.issuerUri = issuerUri;
}
}
替换AuthorizationServerConfig类里硬编码的参数
注入配置类
private final OAuth2Properties oAuth2Properties;
publicAuthorizationServerConfig(OAuth2Properties oAuth2Properties) {
this.oAuth2Properties = oAuth2Properties;
}
替换参数
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient.Builder clientBuilder = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId(oAuth2Properties.getClient().getId())
.clientSecret(oAuth2Properties.getClient().getSecret())
.clientAuthenticationMethod(new ClientAuthenticationMethod(oAuth2Properties.getClient().getAuthenticationMethod()))
.authorizationGrantTypes(grantTypes -> oAuth2Properties.getClient().getGrantTypes().forEach(gt -> grantTypes.add(new AuthorizationGrantType(gt))))
// .redirectUri("http://localhost:8081/login/oauth2/code/client")
.scope(OidcScopes.OPENID)
.scopes(scopes -> scopes.addAll(oAuth2Properties.getClient().getScopes()))
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(oAuth2Properties.getClient().isRequireAuthorizationConsent()).build())
.tokenSettings(TokenSettings.builder()
.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED)
.accessTokenTimeToLive(oAuth2Properties.getToken().getAccessTokenTimeToLive())
.build());
// 添加所有配置的重定向URI
oAuth2Properties.getClient().getRedirectUris().forEach(clientBuilder::redirectUri);
return new InMemoryRegisteredClientRepository(clientBuilder.build());
}
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder()
.issuer(oAuth2Properties.getServer().getIssuerUri())
.build();
}
多redirect_uri处理
一个授权中心,多个应用服务器的情况下,所有应用服务器都会来请求这一个授权中心进行授权拿权限,但每个应用服务器都有自己的域名,这就会产生多种redirect_uri的问题
上面配置文件里和代码中已经处理好了,具体改动如下
oauth2:
client:
redirect-uris:
- http://localhost:8081/login/oauth2/code/client
- http://localhost:8081/login/oauth2/code/client2
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient.Builder clientBuilder = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId(oAuth2Properties.getClient().getId())
.clientSecret(oAuth2Properties.getClient().getSecret())
// ...
;
// 添加所有配置的重定向URI
oAuth2Properties.getClient().getRedirectUris().forEach(clientBuilder::redirectUri);
return new InMemoryRegisteredClientRepository(clientBuilder.build());
}
测试
配置了两个回调地址,就可以使用如下两个链接来进行测试,结果都能正常拿到code
- http://localhost:9000/oauth2/authorize?response_type=code&client_id=client&redirect_uri=http://localhost:8081/login/oauth2/code/client&scope=user
- http://localhost:9000/oauth2/authorize?response_type=code&client_id=client&redirect_uri=http://localhost:8081/login/oauth2/code/client2&scope=user