デザインパターンビルダーモード(Spring-security-oauth2ソースコードClientDetailsS​​erviceConfigurer)



Design Pattern Builder Mode



Builderパターンは、いくつかの単純なオブジェクトを使用して、複雑なオブジェクトを段階的に構築します。このタイプのデザインパターンはに属します作成モードこれは、オブジェクトを作成するための最良の方法を提供します。

簡単なバージョンリファレンス



https://blog.csdn.net/u010102390/article/details/80179754

spring-security-oauth2がどのように再生されるかをご覧ください。



1.最初に、Configurerクラス全体(ClientDetailsS​​erviceConfigurer)を定義します。構成を生成するすべてのクラスがConfigurerで終了することを覚えておいてください。

そのような開催 ClientDetailsS​​erviceBuilder、ClientBuilderを介してクライアントを作成する責任があるClientDetailsS​​erviceBuilderのサブクラス

/** * @author Rob Winch * */ public class ClientDetailsServiceConfigurer extends SecurityConfigurerAdapter { public ClientDetailsServiceConfigurer(ClientDetailsServiceBuilder builder) { setBuilder(builder) } public ClientDetailsServiceBuilder withClientDetails(ClientDetailsService clientDetailsService) throws Exception { setBuilder(getBuilder().clients(clientDetailsService)) return this.and() } public InMemoryClientDetailsServiceBuilder inMemory() throws Exception { InMemoryClientDetailsServiceBuilder next = getBuilder().inMemory() setBuilder(next) return next } public JdbcClientDetailsServiceBuilder jdbc(DataSource dataSource) throws Exception { JdbcClientDetailsServiceBuilder next = getBuilder().jdbc().dataSource(dataSource) setBuilder(next) return next } @Override public void init(ClientDetailsServiceBuilder builder) throws Exception { } @Override public void configure(ClientDetailsServiceBuilder builder) throws Exception { } }

取る InMemoryClientDetailsS​​erviceBuilder 例えば



public class InMemoryClientDetailsServiceBuilder extends ClientDetailsServiceBuilder { private Map clientDetails = new HashMap() @Override protected void addClient(String clientId, ClientDetails value) { clientDetails.put(clientId, value) } @Override protected ClientDetailsService performBuild() { InMemoryClientDetailsService clientDetailsService = new InMemoryClientDetailsService() clientDetailsService.setClientDetailsStore(clientDetails) return clientDetailsService } }

継承 ClientDetailsS​​erviceBuilder

プライベートリストを保持clientBuilders = new ArrayList()すべてのクライアント情報構成を保存します。

public class ClientDetailsServiceBuilder > extends SecurityConfigurerAdapter implements SecurityBuilder { private List clientBuilders = new ArrayList() public InMemoryClientDetailsServiceBuilder inMemory() throws Exception { return new InMemoryClientDetailsServiceBuilder() } public JdbcClientDetailsServiceBuilder jdbc() throws Exception { return new JdbcClientDetailsServiceBuilder() } @SuppressWarnings('rawtypes') public ClientDetailsServiceBuilder clients(final ClientDetailsService clientDetailsService) throws Exception { return new ClientDetailsServiceBuilder() { @Override public ClientDetailsService build() throws Exception { return clientDetailsService } } } / / Set the Client and put it to the list public ClientBuilder withClient(String clientId) { ClientBuilder clientBuilder = new ClientBuilder(clientId) this.clientBuilders.add(clientBuilder) return clientBuilder } 。。。。。。。。。。。。。。。 }

ClientBuilder構成アセンブリクライアントは、内部クラスです

public final class ClientBuilder { private final String clientId private Collection authorizedGrantTypes = new LinkedHashSet() private Collection authorities = new LinkedHashSet() private Integer accessTokenValiditySeconds private Integer refreshTokenValiditySeconds private Collection scopes = new LinkedHashSet() private Collection autoApproveScopes = new HashSet() private String secret private Set registeredRedirectUris = new HashSet() private Set resourceIds = new HashSet() private boolean autoApprove private Map additionalInformation = new LinkedHashMap() private ClientDetails build() { BaseClientDetails result = new BaseClientDetails() result.setClientId(clientId) result.setAuthorizedGrantTypes(authorizedGrantTypes) result.setAccessTokenValiditySeconds(accessTokenValiditySeconds) result.setRefreshTokenValiditySeconds(refreshTokenValiditySeconds) result.setRegisteredRedirectUri(registeredRedirectUris) result.setClientSecret(secret) result.setScope(scopes) result.setAuthorities(AuthorityUtils.createAuthorityList(authorities.toArray(new String[authorities.size()]))) result.setResourceIds(resourceIds) result.setAdditionalInformation(additionalInformation) if (autoApprove) { result.setAutoApproveScopes(scopes) } else { result.setAutoApproveScopes(autoApproveScopes) } return result } public ClientBuilder resourceIds(String... resourceIds) { for (String resourceId : resourceIds) { this.resourceIds.add(resourceId) } return this } public ClientBuilder redirectUris(String... registeredRedirectUris) { for (String redirectUri : registeredRedirectUris) { this.registeredRedirectUris.add(redirectUri) } return this } public ClientBuilder authorizedGrantTypes(String... authorizedGrantTypes) { for (String grant : authorizedGrantTypes) { this.authorizedGrantTypes.add(grant) } return this } public ClientBuilder accessTokenValiditySeconds(int accessTokenValiditySeconds) { this.accessTokenValiditySeconds = accessTokenValiditySeconds return this } public ClientBuilder refreshTokenValiditySeconds(int refreshTokenValiditySeconds) { this.refreshTokenValiditySeconds = refreshTokenValiditySeconds return this } public ClientBuilder secret(String secret) { this.secret = secret return this } public ClientBuilder scopes(String... scopes) { for (String scope : scopes) { this.scopes.add(scope) } return this } public ClientBuilder authorities(String... authorities) { for (String authority : authorities) { this.authorities.add(authority) } return this } public ClientBuilder autoApprove(boolean autoApprove) { this.autoApprove = autoApprove return this } public ClientBuilder autoApprove(String... scopes) { for (String scope : scopes) { this.autoApproveScopes.add(scope) } return this } public ClientBuilder additionalInformation(Map map) { this.additionalInformation.putAll(map) return this } public ClientBuilder additionalInformation(String... pairs) { for (String pair : pairs) { String separator = ':' if (!pair.contains(separator) && pair.contains('=')) { separator = '=' } int index = pair.indexOf(separator) String key = pair.substring(0, index > 0 ? index : pair.length()) String value = index > 0 ? pair.substring(index+1) : null this.additionalInformation.put(key, (Object) value) } return this } public ClientDetailsServiceBuilder and() { return ClientDetailsServiceBuilder.this } private ClientBuilder(String clientId) { this.clientId = clientId } }

4. ClientDetailsS​​erviceConfigurationは、構成に基づいてClientDetailsS​​erviceを作成します

@Configuration public class ClientDetailsServiceConfiguration { @SuppressWarnings('rawtypes') private ClientDetailsServiceConfigurer configurer = new ClientDetailsServiceConfigurer(new ClientDetailsServiceBuilder()) @Bean public ClientDetailsServiceConfigurer clientDetailsServiceConfigurer() { return configurer } @Bean @Lazy @Scope(proxyMode=ScopedProxyMode.INTERFACES) public ClientDetailsService clientDetailsService() throws Exception { return configurer.and().build() } }

ビルドメソッドを見てください

public class ClientDetailsServiceBuilder > extends SecurityConfigurerAdapter implements SecurityBuilder { private List clientBuilders = new ArrayList() ................................................................. @Override public ClientDetailsService build() throws Exception { for (ClientBuilder clientDetailsBldr : clientBuilders) { addClient(clientDetailsBldr.clientId, clientDetailsBldr.build()) } return performBuild() } .................................................................... }

クラス図を見てください

さて、実際のコードを見て、どのように使用するかを見てください。

@Configuration @EnableAuthorizationServer public class SsoAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter{ @Autowired private ClientService clientService /** * Configure the client that can log in to sso */ @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { / / placed in memory InMemoryClientDetailsServiceBuilder builder = clients.inMemory() / / Get all clients List list=clientService.findAll() for(Client config:list) { String scopesStr=ClientDeafaultConstant.SCOPES String authorizedGrantTypesStr=null Long accessTokenValiditySeconds=3600L if(!StringsUtils.hasText(authorizedGrantTypesStr)) { authorizedGrantTypesStr=ClientDeafaultConstant.AUTHORIZED_GRANT_TYPES }else { authorizedGrantTypesStr=config.getAuthorizedGrantTypes() } if(0==config.getAccessTokenValiditySeconds()) { accessTokenValiditySeconds=ClientDeafaultConstant.ACCESSTOKEN_VAILDITY_SECONDS }else { accessTokenValiditySeconds=config.getAccessTokenValiditySeconds() } String[] authorizedGrantTypes=StringUtils.splitByWholeSeparatorPreserveAllTokens(authorizedGrantTypesStr, StringsUtils.COMMA) String[] scopes=StringUtils.splitByWholeSeparatorPreserveAllTokens(scopesStr,StringsUtils.COMMA) / / Build client information builder.withClient(config.getClientKey()) .secret(config.getClientSecret()) .accessTokenValiditySeconds(accessTokenValiditySeconds.intValue()) .authorizedGrantTypes(authorizedGrantTypes) .autoApprove(true) .scopes(scopes) } } .......................................................... }