123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- /*
- * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package org.maxkey.autoconfigure;
- import java.net.URI;
- import java.security.NoSuchAlgorithmException;
- import java.security.spec.InvalidKeySpecException;
- import javax.servlet.Filter;
- import javax.sql.DataSource;
- import org.maxkey.authn.support.jwt.JwtLoginService;
- import org.maxkey.authz.oauth2.common.OAuth2Constants;
- import org.maxkey.authz.oauth2.provider.ClientDetailsService;
- import org.maxkey.authz.oauth2.provider.OAuth2UserDetailsService;
- import org.maxkey.authz.oauth2.provider.approval.TokenApprovalStore;
- import org.maxkey.authz.oauth2.provider.approval.endpoint.OAuth20UserApprovalHandler;
- import org.maxkey.authz.oauth2.provider.client.ClientDetailsUserDetailsService;
- import org.maxkey.authz.oauth2.provider.client.JdbcClientDetailsService;
- import org.maxkey.authz.oauth2.provider.code.AuthorizationCodeServices;
- import org.maxkey.authz.oauth2.provider.code.AuthorizationCodeServicesFactory;
- import org.maxkey.authz.oauth2.provider.endpoint.TokenEndpointAuthenticationFilter;
- import org.maxkey.authz.oauth2.provider.request.DefaultOAuth2RequestFactory;
- import org.maxkey.authz.oauth2.provider.token.TokenStore;
- import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
- import org.maxkey.authz.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.maxkey.authz.oauth2.provider.token.store.TokenStoreFactory;
- import org.maxkey.authz.oidc.idtoken.OIDCIdTokenEnhancer;
- import org.maxkey.configuration.oidc.OIDCProviderMetadataDetails;
- import org.maxkey.crypto.jose.keystore.JWKSetKeyStore;
- import org.maxkey.crypto.jwt.encryption.service.impl.DefaultJwtEncryptionAndDecryptionService;
- import org.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService;
- import org.maxkey.persistence.db.LoginService;
- import org.maxkey.persistence.redis.RedisConnectionFactory;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.boot.web.servlet.FilterRegistrationBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.ComponentScan;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.io.ClassPathResource;
- import org.springframework.jdbc.core.JdbcTemplate;
- import org.springframework.security.authentication.ProviderManager;
- import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
- import org.springframework.security.crypto.password.PasswordEncoder;
- import com.nimbusds.jose.JOSEException;
- import com.nimbusds.jose.JWEAlgorithm;
- @Configuration
- @ComponentScan(basePackages = {
- "org.maxkey.authz.oauth2.provider.endpoint",
- "org.maxkey.authz.oauth2.provider.userinfo.endpoint",
- "org.maxkey.authz.oauth2.provider.approval.controller"
- })
- public class Oauth20AutoConfiguration implements InitializingBean {
- private static final Logger _logger = LoggerFactory.getLogger(Oauth20AutoConfiguration.class);
-
- @Bean
- public FilterRegistrationBean<Filter> TokenEndpointAuthenticationFilter() {
- _logger.debug("TokenEndpointAuthenticationFilter init ");
- FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>();
- registration.setFilter(new TokenEndpointAuthenticationFilter());
- registration.addUrlPatterns(OAuth2Constants.ENDPOINT.ENDPOINT_TOKEN + "/*");
- registration.setName("TokenEndpointAuthenticationFilter");
- registration.setOrder(1);
- return registration;
- }
-
- /**
- * OIDCProviderMetadataDetails.
- * Self-issued Provider Metadata
- * http://openid.net/specs/openid-connect-core-1_0.html#SelfIssued
- */
- @Bean(name = "oidcProviderMetadata")
- public OIDCProviderMetadataDetails OIDCProviderMetadataDetails(
- @Value("${maxkey.oidc.metadata.issuer}")
- String issuer,
- @Value("${maxkey.oidc.metadata.authorizationEndpoint}")
- URI authorizationEndpoint,
- @Value("${maxkey.oidc.metadata.tokenEndpoint}")
- URI tokenEndpoint,
- @Value("${maxkey.oidc.metadata.userinfoEndpoint}")
- URI userinfoEndpoint) {
- _logger.debug("OIDCProviderMetadataDetails init .");
- OIDCProviderMetadataDetails oidcProviderMetadata = new OIDCProviderMetadataDetails();
- oidcProviderMetadata.setIssuer(issuer);
- oidcProviderMetadata.setAuthorizationEndpoint(authorizationEndpoint);
- oidcProviderMetadata.setTokenEndpoint(tokenEndpoint);
- oidcProviderMetadata.setUserinfoEndpoint(userinfoEndpoint);
- return oidcProviderMetadata;
- }
- /**
- * jwtSetKeyStore.
- * @return
- */
- @Bean(name = "jwkSetKeyStore")
- public JWKSetKeyStore jwtSetKeyStore() {
- JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore();
- ClassPathResource classPathResource = new ClassPathResource("/config/keystore.jwks");
- jwkSetKeyStore.setLocation(classPathResource);
- return jwkSetKeyStore;
- }
-
- /**
- * jwtSetKeyStore.
- * @return
- * @throws JOSEException
- * @throws InvalidKeySpecException
- * @throws NoSuchAlgorithmException
- */
- @Bean(name = "jwtSignerValidationService")
- public DefaultJwtSigningAndValidationService jwtSignerValidationService(
- JWKSetKeyStore jwtSetKeyStore)
- throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
- DefaultJwtSigningAndValidationService jwtSignerValidationService =
- new DefaultJwtSigningAndValidationService(jwtSetKeyStore);
- jwtSignerValidationService.setDefaultSignerKeyId("maxkey_rsa");
- jwtSignerValidationService.setDefaultSigningAlgorithmName("RS256");
- return jwtSignerValidationService;
- }
-
- /**
- * jwtSetKeyStore.
- * @return
- * @throws JOSEException
- * @throws InvalidKeySpecException
- * @throws NoSuchAlgorithmException
- */
- @Bean(name = "jwtEncryptionService")
- public DefaultJwtEncryptionAndDecryptionService jwtEncryptionService(
- JWKSetKeyStore jwtSetKeyStore)
- throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
- DefaultJwtEncryptionAndDecryptionService jwtEncryptionService =
- new DefaultJwtEncryptionAndDecryptionService(jwtSetKeyStore);
- jwtEncryptionService.setDefaultAlgorithm(JWEAlgorithm.RSA1_5);//RSA1_5
- jwtEncryptionService.setDefaultDecryptionKeyId("maxkey_rsa");
- jwtEncryptionService.setDefaultEncryptionKeyId("maxkey_rsa");
- return jwtEncryptionService;
- }
-
- /**
- * JwtLoginService.
- * @return
- */
- @Bean(name = "jwtLoginService")
- public JwtLoginService jwtLoginService(
- DefaultJwtSigningAndValidationService jwtSignerValidationService,
- OIDCProviderMetadataDetails oidcProviderMetadata) {
-
- JwtLoginService jwtLoginService = new JwtLoginService(
- oidcProviderMetadata,
- jwtSignerValidationService
- );
- return jwtLoginService;
- }
-
-
- /**
- * tokenEnhancer.
- * @return
- */
- @Bean(name = "tokenEnhancer")
- public OIDCIdTokenEnhancer tokenEnhancer(
- DefaultJwtSigningAndValidationService jwtSignerValidationService,
- DefaultJwtEncryptionAndDecryptionService jwtEncryptionService,
- OIDCProviderMetadataDetails oidcProviderMetadata,
- ClientDetailsService oauth20JdbcClientDetailsService) {
- OIDCIdTokenEnhancer tokenEnhancer = new OIDCIdTokenEnhancer();
- tokenEnhancer.setJwtSignerService(jwtSignerValidationService);
- tokenEnhancer.setJwtEnDecryptionService(jwtEncryptionService);
- tokenEnhancer.setClientDetailsService(oauth20JdbcClientDetailsService);
- tokenEnhancer.setProviderMetadata(oidcProviderMetadata);
- return tokenEnhancer;
- }
- //以上部分为了支持OpenID Connect 1.0
-
-
- /**
- * AuthorizationCodeServices.
- * @param persistence int
- * @return oauth20AuthorizationCodeServices
- */
- @Bean(name = "oauth20AuthorizationCodeServices")
- public AuthorizationCodeServices oauth20AuthorizationCodeServices(
- @Value("${maxkey.server.persistence}") int persistence,
- JdbcTemplate jdbcTemplate,
- RedisConnectionFactory redisConnFactory) {
- return new AuthorizationCodeServicesFactory().getService(persistence, jdbcTemplate, redisConnFactory);
- }
-
- /**
- * TokenStore.
- * @param persistence int
- * @return oauth20TokenStore
- */
- @Bean(name = "oauth20TokenStore")
- public TokenStore oauth20TokenStore(
- @Value("${maxkey.server.persistence}") int persistence,
- JdbcTemplate jdbcTemplate,
- RedisConnectionFactory redisConnFactory) {
-
- return new TokenStoreFactory().getTokenStore(persistence, jdbcTemplate, redisConnFactory);
- }
-
- /**
- * jwtAccessTokenConverter.
- * @return converter
- */
- @Bean(name = "converter")
- public JwtAccessTokenConverter jwtAccessTokenConverter() {
- JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
- return jwtAccessTokenConverter;
- }
-
- /**
- * clientDetailsService.
- * @return oauth20JdbcClientDetailsService
- */
- @Bean(name = "oauth20JdbcClientDetailsService")
- public JdbcClientDetailsService clientDetailsService(DataSource dataSource,PasswordEncoder passwordReciprocal) {
- JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
- clientDetailsService.setPasswordEncoder(passwordReciprocal);
- return clientDetailsService;
- }
-
- /**
- * clientDetailsUserDetailsService.
- * @return oauth20TokenServices
- */
- @Bean(name = "oauth20TokenServices")
- public DefaultTokenServices DefaultTokenServices(
- JdbcClientDetailsService oauth20JdbcClientDetailsService,
- TokenStore oauth20TokenStore,
- OIDCIdTokenEnhancer tokenEnhancer) {
- DefaultTokenServices tokenServices = new DefaultTokenServices();
- tokenServices.setClientDetailsService(oauth20JdbcClientDetailsService);
- tokenServices.setTokenEnhancer(tokenEnhancer);
- tokenServices.setTokenStore(oauth20TokenStore);
- tokenServices.setSupportRefreshToken(true);
- return tokenServices;
- }
-
-
- /**
- * TokenApprovalStore.
- * @return oauth20ApprovalStore
- */
- @Bean(name = "oauth20ApprovalStore")
- public TokenApprovalStore tokenApprovalStore(
- TokenStore oauth20TokenStore) {
- TokenApprovalStore tokenApprovalStore = new TokenApprovalStore();
- tokenApprovalStore.setTokenStore(oauth20TokenStore);
- return tokenApprovalStore;
- }
-
-
- /**
- * OAuth2RequestFactory.
- * @return oAuth2RequestFactory
- */
- @Bean(name = "oAuth2RequestFactory")
- public DefaultOAuth2RequestFactory oauth2RequestFactory(
- JdbcClientDetailsService oauth20JdbcClientDetailsService) {
- DefaultOAuth2RequestFactory oauth2RequestFactory =
- new DefaultOAuth2RequestFactory(oauth20JdbcClientDetailsService);
- return oauth2RequestFactory;
- }
-
- /**
- * OAuth20UserApprovalHandler.
- * @return oauth20UserApprovalHandler
- */
- @Bean(name = "oauth20UserApprovalHandler")
- public OAuth20UserApprovalHandler oauth20UserApprovalHandler(
- JdbcClientDetailsService oauth20JdbcClientDetailsService,
- DefaultOAuth2RequestFactory oAuth2RequestFactory,
- TokenApprovalStore oauth20ApprovalStore
- ) {
- OAuth20UserApprovalHandler userApprovalHandler = new OAuth20UserApprovalHandler();
- userApprovalHandler.setApprovalStore(oauth20ApprovalStore);
- userApprovalHandler.setRequestFactory(oAuth2RequestFactory);
- userApprovalHandler.setClientDetailsService(oauth20JdbcClientDetailsService);
- return userApprovalHandler;
- }
-
- /**
- * ProviderManager.
- * @return oauth20UserAuthenticationManager
- */
- @Bean(name = "oauth20UserAuthenticationManager")
- public ProviderManager oauth20UserAuthenticationManager(
- PasswordEncoder passwordEncoder,
- LoginService loginService
- ) {
-
- OAuth2UserDetailsService userDetailsService =new OAuth2UserDetailsService();
- userDetailsService.setLoginService(loginService);
-
- DaoAuthenticationProvider daoAuthenticationProvider= new DaoAuthenticationProvider();
- daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
- daoAuthenticationProvider.setUserDetailsService(userDetailsService);
- ProviderManager authenticationManager = new ProviderManager(daoAuthenticationProvider);
- return authenticationManager;
- }
-
- /**
- * ProviderManager.
- * @return oauth20ClientAuthenticationManager
- */
- @Bean(name = "oauth20ClientAuthenticationManager")
- public ProviderManager oauth20ClientAuthenticationManager(
- JdbcClientDetailsService oauth20JdbcClientDetailsService,
- PasswordEncoder passwordReciprocal
- ) {
-
- ClientDetailsUserDetailsService cientDetailsUserDetailsService =
- new ClientDetailsUserDetailsService(oauth20JdbcClientDetailsService);
-
- DaoAuthenticationProvider daoAuthenticationProvider= new DaoAuthenticationProvider();
- daoAuthenticationProvider.setPasswordEncoder(passwordReciprocal);
- daoAuthenticationProvider.setUserDetailsService(cientDetailsUserDetailsService);
- ProviderManager authenticationManager = new ProviderManager(daoAuthenticationProvider);
- return authenticationManager;
- }
-
-
- @Override
- public void afterPropertiesSet() throws Exception {
- // TODO Auto-generated method stub
-
- }
- }
|