├── .gitignore
├── LICENSE
├── README.md
├── myoidc-client
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── myoidc
│ │ │ └── client
│ │ │ ├── MyOIDCClientApplication.java
│ │ │ ├── config
│ │ │ ├── MVCConfiguration.java
│ │ │ └── MyOIDCConfiguration.java
│ │ │ ├── domain
│ │ │ ├── DiscoveryEndpointInfo.java
│ │ │ ├── RPHolder.java
│ │ │ ├── RPHolderRepository.java
│ │ │ └── shared
│ │ │ │ ├── Application.java
│ │ │ │ └── BeanProvider.java
│ │ │ ├── infrastructure
│ │ │ └── RPHolderRepositoryDefault.java
│ │ │ ├── service
│ │ │ ├── MyOIDCClientService.java
│ │ │ ├── business
│ │ │ │ ├── OIDCTokenVerifier.java
│ │ │ │ ├── PasswordOAuth2Handler.java
│ │ │ │ └── PasswordParams.java
│ │ │ ├── dto
│ │ │ │ ├── AbstractOauthDto.java
│ │ │ │ ├── AccessTokenDto.java
│ │ │ │ ├── AuthAccessTokenDto.java
│ │ │ │ ├── AuthCallbackDto.java
│ │ │ │ ├── AuthorizationCodeDto.java
│ │ │ │ ├── RefreshAccessTokenDto.java
│ │ │ │ └── UserInfoDto.java
│ │ │ └── impl
│ │ │ │ └── MyOIDCClientServiceImpl.java
│ │ │ └── web
│ │ │ ├── WebUtils.java
│ │ │ ├── context
│ │ │ ├── OIDCApplicationContextAware.java
│ │ │ └── OIDCServletContextAware.java
│ │ │ └── controller
│ │ │ ├── AuthorizationCodeController.java
│ │ │ ├── ClientCredentialsController.java
│ │ │ ├── ImplicitController.java
│ │ │ ├── PasswordController.java
│ │ │ ├── RefreshTokenController.java
│ │ │ ├── StartupController.java
│ │ │ └── UserInfoController.java
│ └── resources
│ │ ├── application.properties
│ │ ├── static
│ │ ├── angular.min.js
│ │ ├── bootstrap
│ │ │ ├── css
│ │ │ │ ├── bootstrap-theme.css
│ │ │ │ ├── bootstrap-theme.min.css
│ │ │ │ ├── bootstrap.css
│ │ │ │ └── bootstrap.min.css
│ │ │ ├── fonts
│ │ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ │ └── glyphicons-halflings-regular.woff2
│ │ │ └── js
│ │ │ │ ├── bootstrap.js
│ │ │ │ └── bootstrap.min.js
│ │ └── favicon.ico
│ │ └── templates
│ │ ├── access_token_result.html
│ │ ├── authorization_code.html
│ │ ├── client_credentials.html
│ │ ├── code_access_token.html
│ │ ├── error
│ │ └── 405.html
│ │ ├── fragment
│ │ ├── footer.html
│ │ └── header.html
│ │ ├── implicit.html
│ │ ├── index.html
│ │ ├── oauth_error.html
│ │ ├── password.html
│ │ ├── refresh_token.html
│ │ └── user_info.html
│ └── test
│ ├── java
│ └── myoidc
│ │ └── client
│ │ ├── MyOIDCClientApplicationTest.java
│ │ ├── domain
│ │ └── DiscoveryEndpointInfoTest.java
│ │ ├── infrastructure
│ │ └── RPHolderRepositoryDefaultTest.java
│ │ └── service
│ │ └── business
│ │ └── PasswordOAuth2HandlerTest.java
│ └── resources
│ └── application-test.properties
├── myoidc-server
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── myoidc
│ │ │ └── server
│ │ │ ├── Constants.java
│ │ │ ├── MyOIDCServerApplication.java
│ │ │ ├── config
│ │ │ ├── MVCConfiguration.java
│ │ │ ├── MyOIDCConfiguration.java
│ │ │ ├── OAuth2MethodSecurityConfiguration.java
│ │ │ ├── OAuth2ServerConfiguration.java
│ │ │ └── SecurityConfiguration.java
│ │ │ ├── domain
│ │ │ ├── AbstractDomain.java
│ │ │ ├── README.txt
│ │ │ ├── oauth
│ │ │ │ ├── OauthClientDetails.java
│ │ │ │ └── OauthRepository.java
│ │ │ ├── security
│ │ │ │ ├── OIDCUserDetails.java
│ │ │ │ ├── SecurityHolder.java
│ │ │ │ └── SecurityUtils.java
│ │ │ ├── shared
│ │ │ │ ├── Application.java
│ │ │ │ ├── BeanProvider.java
│ │ │ │ ├── Repository.java
│ │ │ │ └── UUIDGenerator.java
│ │ │ └── user
│ │ │ │ ├── Privilege.java
│ │ │ │ ├── User.java
│ │ │ │ ├── UserPrivilege.java
│ │ │ │ └── UserRepository.java
│ │ │ ├── infrastructure
│ │ │ ├── PasswordHandler.java
│ │ │ ├── README.txt
│ │ │ ├── RandomUtils.java
│ │ │ ├── jdbc
│ │ │ │ ├── OauthClientDetailsRowMapper.java
│ │ │ │ └── OauthRepositoryJdbc.java
│ │ │ ├── jpa
│ │ │ │ ├── AbstractRepositoryHibernate.java
│ │ │ │ └── UserRepositoryHibernate.java
│ │ │ └── oidc
│ │ │ │ ├── MyOIDCAccessTokenConverter.java
│ │ │ │ ├── MyOIDCJwtAccessTokenConverter.java
│ │ │ │ ├── MyOIDCTokenStore.java
│ │ │ │ ├── MyOIDCUserAuthenticationConverter.java
│ │ │ │ ├── OIDCUseScene.java
│ │ │ │ └── OIDCUtils.java
│ │ │ ├── service
│ │ │ ├── OauthService.java
│ │ │ ├── README.txt
│ │ │ ├── SecurityService.java
│ │ │ ├── UserService.java
│ │ │ ├── business
│ │ │ │ ├── ClientRegistrationFormSaver.java
│ │ │ │ ├── OAuthClientDetailsSaver.java
│ │ │ │ └── UserFormSaver.java
│ │ │ ├── dto
│ │ │ │ ├── ClientRegistrationFormDto.java
│ │ │ │ ├── OAuthResourceDto.java
│ │ │ │ ├── OauthClientDetailsDto.java
│ │ │ │ ├── UserDto.java
│ │ │ │ ├── UserFormDto.java
│ │ │ │ ├── UserJsonDto.java
│ │ │ │ └── UserListDto.java
│ │ │ ├── impl
│ │ │ │ ├── OauthServiceImpl.java
│ │ │ │ ├── SecurityServiceImpl.java
│ │ │ │ └── UserServiceImpl.java
│ │ │ ├── oauth
│ │ │ │ ├── CurrentUserJsonDtoLoader.java
│ │ │ │ ├── CustomJdbcClientDetailsService.java
│ │ │ │ ├── CustomJdbcTokenStore.java
│ │ │ │ ├── OauthUserApprovalHandler.java
│ │ │ │ └── SOSAuthorizationCodeServices.java
│ │ │ └── validation
│ │ │ │ ├── ClientIdValidation.java
│ │ │ │ ├── ClientIdValidator.java
│ │ │ │ ├── UsernameValidation.java
│ │ │ │ └── UsernameValidator.java
│ │ │ └── web
│ │ │ ├── README.txt
│ │ │ ├── WebUtils.java
│ │ │ ├── context
│ │ │ ├── OIDCApplicationContextAware.java
│ │ │ ├── OIDCServletContextAware.java
│ │ │ └── SpringSecurityHolder.java
│ │ │ ├── controller
│ │ │ ├── MyOIDCController.java
│ │ │ ├── OAuth2RestController.java
│ │ │ ├── admin
│ │ │ │ ├── AdminRPController.java
│ │ │ │ └── AdminUserController.java
│ │ │ ├── endpoint
│ │ │ │ ├── DiscoveryEndpoint.java
│ │ │ │ ├── JWKSEndpoint.java
│ │ │ │ ├── RegistrationEndpoint.java
│ │ │ │ └── UserInfoEndpoint.java
│ │ │ └── resource
│ │ │ │ ├── MobileController.java
│ │ │ │ └── UnityController.java
│ │ │ └── filter
│ │ │ └── ExtCharacterEncodingFilter.java
│ └── resources
│ │ ├── application.properties
│ │ ├── jwks.json
│ │ ├── public
│ │ ├── MyOIDC_API-1.1.0.html
│ │ ├── angular.min.js
│ │ ├── bootstrap
│ │ │ ├── css
│ │ │ │ ├── bootstrap-theme.css
│ │ │ │ ├── bootstrap-theme.min.css
│ │ │ │ ├── bootstrap.css
│ │ │ │ └── bootstrap.min.css
│ │ │ ├── fonts
│ │ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ │ └── glyphicons-halflings-regular.woff2
│ │ │ └── js
│ │ │ │ ├── bootstrap.js
│ │ │ │ └── bootstrap.min.js
│ │ ├── db_table_description.html
│ │ ├── favicon.ico
│ │ └── images
│ │ │ ├── oidc-sm.png
│ │ │ └── openid.png
│ │ └── templates
│ │ ├── admin
│ │ ├── rp_client_test.html
│ │ ├── rp_form.html
│ │ ├── rp_list.html
│ │ ├── user_form.html
│ │ └── user_list.html
│ │ ├── fragment
│ │ ├── footer.html
│ │ └── header.html
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── registration_form.html
│ │ ├── registration_pre.html
│ │ └── registration_success.html
│ └── test
│ ├── java
│ └── myoidc
│ │ └── server
│ │ ├── ContextTest.java
│ │ ├── JwkTokenStoreTest.java
│ │ ├── MyOIDCServerApplicationTests.java
│ │ ├── configuration
│ │ └── SecurityConfigurationTest.java
│ │ ├── domain
│ │ └── shared
│ │ │ └── UUIDGeneratorTest.java
│ │ ├── infrastructure
│ │ ├── AbstractRepositoryTest.java
│ │ ├── Auth0JwtTest.java
│ │ ├── JJwtTest.java
│ │ ├── JWKSTest.java
│ │ ├── Jose4JTest.java
│ │ ├── JsonWebKeySetTest.java
│ │ ├── NimbusJoseJwtTest.java
│ │ ├── PasswordHandlerTest.java
│ │ ├── PrimeJwtTest.java
│ │ ├── RandomUtilsTest.java
│ │ ├── VertxAuthJwtTest.java
│ │ ├── jdbc
│ │ │ └── OauthRepositoryJdbcTest.java
│ │ ├── jpa
│ │ │ └── UserRepositoryHibernateTest.java
│ │ └── oidc
│ │ │ └── OIDCUtilsTest.java
│ │ └── service
│ │ └── business
│ │ └── ClientRegistrationFormSaverTest.java
│ └── resources
│ ├── application-test.properties
│ ├── jwks_ec.json
│ ├── jwks_oct.json
│ ├── jwks_rsa.json
│ └── keystore.jwks
├── others
├── Final_OpenID-Connect-Core-1.0-incorporating-errata-set-1.html
├── How-To-Use.txt
├── OpenID Connect Standard for Federation.pdf
├── database
│ ├── initial-db.ddl
│ └── myoidc-server.ddl
├── development-log.txt
├── images
│ ├── Security-Token-Service.png
│ ├── favicon.ico
│ └── openid.png
├── key
│ ├── private_key.json
│ └── public_key.json
├── oidc_test.txt
└── springboot
│ ├── myoidc.zip
│ └── spring-boot-reference(2.0.0).pdf
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 |
12 | ### IntelliJ IDEA ###
13 | .idea
14 | *.iws
15 | *.iml
16 | *.ipr
17 |
18 | ### NetBeans ###
19 | nbproject/private/
20 | build/
21 | nbbuild/
22 | dist/
23 | nbdist/
24 | .nb-gradle/
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/MyOIDCClientApplication.java:
--------------------------------------------------------------------------------
1 | package myoidc.client;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * Spring Boot bootstrap
8 | */
9 | @SpringBootApplication
10 | public class MyOIDCClientApplication {
11 |
12 |
13 | /**
14 | * Run it directly
15 | *
16 | * @param args args
17 | */
18 | public static void main(String[] args) {
19 | SpringApplication.run(MyOIDCClientApplication.class, args);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/config/MVCConfiguration.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.config;
2 |
3 |
4 |
5 | import myoidc.client.domain.shared.Application;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.http.converter.HttpMessageConverter;
8 | import org.springframework.http.converter.StringHttpMessageConverter;
9 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
10 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
11 |
12 | import java.nio.charset.Charset;
13 | import java.util.List;
14 |
15 | /**
16 | * 2018/1/30
17 | *
18 | * Spring MVC 扩展配置
19 | *
20 | *
21 | * @author Shengzhao Li
22 | */
23 | @Configuration
24 | public class MVCConfiguration implements WebMvcConfigurer {
25 |
26 |
27 | /**
28 | * 扩展拦截器
29 | */
30 | @Override
31 | public void addInterceptors(InterceptorRegistry registry) {
32 |
33 | WebMvcConfigurer.super.addInterceptors(registry);
34 | }
35 |
36 |
37 | // /**
38 | // * 字符编码配置 UTF-8
39 | // */
40 | // @Bean
41 | // public FilterRegistrationBean encodingFilter() {
42 | // FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
43 | // registrationBean.setFilter(new ExtCharacterEncodingFilter());
44 | // registrationBean.addUrlPatterns("/*");
45 | // return registrationBean;
46 | // }
47 |
48 |
49 | /**
50 | * 解决乱码问题
51 | * For UTF-8
52 | */
53 | @Override
54 | public void configureMessageConverters(List> converters) {
55 | WebMvcConfigurer.super.configureMessageConverters(converters);
56 | converters.add(new StringHttpMessageConverter(Charset.forName(Application.ENCODING)));
57 | }
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/config/MyOIDCConfiguration.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.config;
2 |
3 |
4 | import myoidc.client.domain.shared.Application;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.web.client.RestTemplate;
9 |
10 |
11 | /**
12 | * 2018/1/30
13 | *
14 | *
15 | * @author Shengzhao Li
16 | */
17 | @Configuration
18 | public class MyOIDCConfiguration {
19 |
20 |
21 | @Value("${application.host}")
22 | private String host;
23 |
24 |
25 | // Application
26 | @Bean
27 | public Application application() {
28 | Application application = new Application();
29 | application.setHost(host);
30 | return application;
31 | }
32 |
33 |
34 | @Bean
35 | public RestTemplate restTemplate() {
36 | return new RestTemplate();
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/domain/RPHolderRepository.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.domain;
2 |
3 | /**
4 | * 2020/4/7
5 | *
6 | * @author Shengzhao Li
7 | * @since 1.1.0
8 | */
9 | public interface RPHolderRepository {
10 |
11 | RPHolder findRPHolder();
12 |
13 | boolean saveRPHolder(RPHolder rpHolder);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/domain/shared/Application.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.domain.shared;
2 |
3 |
4 | import org.springframework.beans.factory.InitializingBean;
5 | import org.springframework.util.Assert;
6 |
7 | /**
8 | * @author Shengzhao Li
9 | */
10 | public class Application implements InitializingBean {
11 |
12 | //系统字符编码
13 | public static final String ENCODING = "UTF-8";
14 |
15 | public static final String PROJECT_HOME = "https://github.com/monkeyk/MyOIDC";
16 | //Current version
17 | public static final String VERSION = "1.1.1";
18 |
19 |
20 | //application host
21 | private static String host;
22 |
23 |
24 | /*
25 | * default
26 | * */
27 | public Application() {
28 | }
29 |
30 |
31 | public static String host() {
32 | return host;
33 | }
34 |
35 | public void setHost(String host) {
36 | Application.host = host.endsWith("/") ? host : host + "/";
37 | }
38 |
39 |
40 | @Override
41 | public void afterPropertiesSet() throws Exception {
42 | Assert.notNull(host, "host is null");
43 | }
44 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/domain/shared/BeanProvider.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.domain.shared;
2 |
3 | import org.springframework.context.ApplicationContext;
4 |
5 | /**
6 | * Get Bean form ApplicationContext
7 | *
8 | * @author Shengzhao Li
9 | * @since 1.1.0
10 | */
11 | public abstract class BeanProvider {
12 |
13 | protected static ApplicationContext applicationContext;
14 |
15 | protected BeanProvider() {
16 | }
17 |
18 | public static void initialize(ApplicationContext applicationContext) {
19 | BeanProvider.applicationContext = applicationContext;
20 | }
21 |
22 | /**
23 | * Get Bean by clazz.
24 | *
25 | * @param clazz Class
26 | * @param class type
27 | * @return Bean instance
28 | */
29 | public static T getBean(Class clazz) {
30 | if (applicationContext == null) {
31 | return null;
32 | }
33 | return applicationContext.getBean(clazz);
34 | }
35 |
36 | @SuppressWarnings("unchecked")
37 | public static T getBean(String beanId) {
38 | if (applicationContext == null) {
39 | return null;
40 | }
41 | return (T) applicationContext.getBean(beanId);
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/infrastructure/RPHolderRepositoryDefault.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.infrastructure;
2 |
3 | import myoidc.client.domain.RPHolder;
4 | import myoidc.client.domain.RPHolderRepository;
5 | import org.apache.commons.lang3.StringUtils;
6 | import org.jose4j.json.JsonUtil;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.stereotype.Repository;
10 | import org.springframework.util.FileCopyUtils;
11 |
12 | import java.io.File;
13 | import java.io.FileReader;
14 | import java.io.FileWriter;
15 | import java.io.IOException;
16 | import java.util.Map;
17 |
18 | /**
19 | * 2020/4/7
20 | *
21 | * 默认存储 RPHolder 在临时文件中/
22 | *
23 | * 实际使用时用具体的实现(如存数据库)
24 | *
25 | * @author Shengzhao Li
26 | * @since 1.1.0
27 | */
28 | @Repository
29 | public class RPHolderRepositoryDefault implements RPHolderRepository {
30 |
31 | private static final Logger LOG = LoggerFactory.getLogger(RPHolderRepositoryDefault.class);
32 |
33 | //文件名
34 | private static final String FILE = "myoidc-client-rpholder.json";
35 |
36 |
37 | //临时文件对象
38 | private File file;
39 |
40 | @Override
41 | public RPHolder findRPHolder() {
42 | try {
43 | File file = getFile();
44 | String json = FileCopyUtils.copyToString(new FileReader(file));
45 | if(StringUtils.isNotBlank(json)){
46 | Map map = JsonUtil.parseJson(json);
47 | return new RPHolder(map);
48 | }
49 | } catch (Exception e) {
50 | LOG.error("File handle error", e);
51 | }
52 | //返回一空对象
53 | return new RPHolder();
54 | }
55 |
56 | @Override
57 | public boolean saveRPHolder(RPHolder rpHolder) {
58 | try {
59 | File file = getFile();
60 | String json = rpHolder.toJSON();
61 | FileCopyUtils.copy(json, new FileWriter(file));
62 | return true;
63 | } catch (IOException e) {
64 | LOG.error("File handle error", e);
65 | }
66 | return false;
67 | }
68 |
69 | private File getFile() throws IOException {
70 | if (file != null && file.exists()) {
71 | LOG.debug("Use cached file: {}", file);
72 | return file;
73 | }
74 | file = new File(FILE);
75 | if (!file.exists()) {
76 | boolean ok = file.createNewFile();
77 | LOG.debug("Create file: {} result: {}", FILE, ok);
78 | }
79 | return file;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/MyOIDCClientService.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service;
2 |
3 |
4 | import myoidc.client.domain.RPHolder;
5 | import myoidc.client.service.dto.*;
6 |
7 | import java.util.Map;
8 |
9 | /**
10 | * 2020/4/7
11 | *
12 | * @author Shengzhao Li
13 | * @since 1.1.0
14 | */
15 | public interface MyOIDCClientService {
16 |
17 | RPHolder loadRPHolder();
18 |
19 | boolean saveRPHolder(RPHolder rpHolder);
20 |
21 | AuthAccessTokenDto createAuthAccessTokenDto(AuthCallbackDto callbackDto);
22 |
23 | AccessTokenDto retrieveAccessTokenDto(AuthAccessTokenDto tokenDto);
24 |
25 | UserInfoDto loadUserInfoDto(String access_token);
26 |
27 | Map verifyToken(String token);
28 |
29 | AccessTokenDto retrieveCredentialsAccessTokenDto(AuthAccessTokenDto tokenDto);
30 |
31 | AccessTokenDto retrievePasswordAccessTokenDto(AuthAccessTokenDto authAccessTokenDto);
32 |
33 | AccessTokenDto refreshAccessTokenDto(RefreshAccessTokenDto refreshAccessTokenDto);
34 | }
35 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/business/OIDCTokenVerifier.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service.business;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import myoidc.client.domain.RPHolder;
5 | import org.jose4j.jwk.HttpsJwks;
6 | import org.jose4j.jwt.JwtClaims;
7 | import org.jose4j.jwt.consumer.InvalidJwtException;
8 | import org.jose4j.jwt.consumer.JwtConsumer;
9 | import org.jose4j.jwt.consumer.JwtConsumerBuilder;
10 | import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver;
11 | import org.jose4j.keys.resolvers.VerificationKeyResolver;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | import java.util.Map;
16 |
17 | import static myoidc.client.domain.RPHolder.RESOURCE_ID;
18 |
19 | /**
20 | * 2020/4/12
21 | *
22 | * @author Shengzhao Li
23 | * @since 1.1.0
24 | */
25 | public class OIDCTokenVerifier {
26 |
27 |
28 | private static final Logger LOG = LoggerFactory.getLogger(OIDCTokenVerifier.class);
29 |
30 | private final RPHolder rpHolder;
31 | private final String token;
32 |
33 | public OIDCTokenVerifier(RPHolder rpHolder, String token) {
34 | this.rpHolder = rpHolder;
35 | this.token = token;
36 | }
37 |
38 | public Map verify() {
39 |
40 | VerificationKeyResolver verificationKeyResolver = new HttpsJwksVerificationKeyResolver(new HttpsJwks(rpHolder.getDiscoveryEndpointInfo().getJwks_uri()));
41 | JwtConsumer consumer = new JwtConsumerBuilder()
42 | .setVerificationKeyResolver(verificationKeyResolver)
43 | //此处有许可项可配置进行校验,请根据实际需要配置
44 | //更多帮助可访问 https://bitbucket.org/b_c/jose4j/wiki/JWT%20Examples
45 | .setRequireExpirationTime()
46 | .setRequireSubject()
47 | .setRequireIssuedAt()
48 | .setExpectedAudience(RESOURCE_ID)
49 | // .setRequireNotBefore()
50 | // .setRequireJwtId()
51 | .build();
52 | try {
53 | JwtClaims claims = consumer.processToClaims(token);
54 | return claims.getClaimsMap();
55 | } catch (InvalidJwtException e) {
56 | LOG.warn("Verify token failed", e);
57 | return ImmutableMap.of("error", "verify_failed", "error_details", e.getErrorDetails());
58 | }
59 |
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/business/PasswordOAuth2Handler.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service.business;
2 |
3 |
4 | import myoidc.client.domain.shared.BeanProvider;
5 | import myoidc.client.service.dto.AccessTokenDto;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.web.client.RestClientException;
9 | import org.springframework.web.client.RestTemplate;
10 |
11 | /**
12 | * Handle 'password' type actions
13 | *
14 | * http://localhost:8080/oauth/token?client_id=mobile-client&client_secret=mobile&grant_type=password&scope=read,write&username=mobile&password=mobile
15 | *
16 | * How to use?
17 | * Please see unit-test PasswordOAuth2HandlerTest
18 | * From spring-oauth-client(https://gitee.com/mkk/spring-oauth-client)
19 | *
20 | * @author Shengzhao Li
21 | * @since 1.1.0
22 | */
23 | public class PasswordOAuth2Handler {
24 |
25 | private static final Logger LOG = LoggerFactory.getLogger(PasswordOAuth2Handler.class);
26 |
27 | private transient RestTemplate restTemplate = BeanProvider.getBean(RestTemplate.class);
28 |
29 | public PasswordOAuth2Handler() {
30 | }
31 |
32 | /**
33 | * Step 1:
34 | * Get access token from Oauth server
35 | *
36 | * Response Data:
37 | * {"access_token":"9d0a2372-d039-4c1a-b0f9-762be10d531c","token_type":"bearer","refresh_token":"cfe0866d-d712-4ec2-9f23-ddb61443c9db","expires_in":38818,"scope":"read write"}
38 | *
39 | * Error Data:
40 | *
41 | * Bad client credentials
42 | * invalid_client
43 | *
44 | *
45 | * or
46 | * {"error":"invalid_grant","error_description":"Bad credentials"}
47 | *
48 | * @return AccessTokenDto
49 | */
50 | public AccessTokenDto getAccessToken(PasswordParams params) {
51 | final String fullUri = params.getFullUri();
52 | LOG.debug("Get 'access_token' uri: {}", fullUri);
53 |
54 | try {
55 | return restTemplate.postForObject(fullUri, null, AccessTokenDto.class);
56 | } catch (RestClientException e) {
57 | LOG.error("Send request to: {} error", fullUri, e);
58 | return new AccessTokenDto("request_error", e.getMessage());
59 | }
60 | }
61 |
62 |
63 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/business/PasswordParams.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service.business;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 'password' params
7 | * From spring-oauth-client(https://gitee.com/mkk/spring-oauth-client)
8 | *
9 | * @author Shengzhao Li
10 | * @since 1.1.0
11 | */
12 | public class PasswordParams implements Serializable {
13 |
14 | //Fixed value
15 | public static final String GRANT_TYPE = "password";
16 | private static final long serialVersionUID = 1671832786634202458L;
17 |
18 |
19 | private String accessTokenUri;
20 |
21 | private String clientId;
22 | private String clientSecret;
23 |
24 | private String username;
25 | private String password;
26 |
27 |
28 | //Scope, default 'openid'
29 | private String scope = "openid";
30 |
31 | /**
32 | * Construct by ''accessTokenUri
33 | *
34 | * @param accessTokenUri Access Token Uri
35 | */
36 | public PasswordParams(String accessTokenUri) {
37 | this.accessTokenUri = accessTokenUri;
38 | }
39 |
40 | public String getAccessTokenUri() {
41 | return accessTokenUri;
42 | }
43 |
44 | public PasswordParams setAccessTokenUri(String accessTokenUri) {
45 | this.accessTokenUri = accessTokenUri;
46 | return this;
47 | }
48 |
49 | public String getClientId() {
50 | return clientId;
51 | }
52 |
53 | public PasswordParams setClientId(String clientId) {
54 | this.clientId = clientId;
55 | return this;
56 | }
57 |
58 | public String getClientSecret() {
59 | return clientSecret;
60 | }
61 |
62 | public PasswordParams setClientSecret(String clientSecret) {
63 | this.clientSecret = clientSecret;
64 | return this;
65 | }
66 |
67 | public String getUsername() {
68 | return username;
69 | }
70 |
71 | public PasswordParams setUsername(String username) {
72 | this.username = username;
73 | return this;
74 | }
75 |
76 | public String getPassword() {
77 | return password;
78 | }
79 |
80 | public PasswordParams setPassword(String password) {
81 | this.password = password;
82 | return this;
83 | }
84 |
85 | public String getGrantType() {
86 | return GRANT_TYPE;
87 | }
88 |
89 |
90 | public String getScope() {
91 | return scope;
92 | }
93 |
94 | public PasswordParams setScope(String scope) {
95 | this.scope = scope;
96 | return this;
97 | }
98 |
99 | /*
100 | * http://localhost:8080/oauth/token?client_id=mobile-client&client_secret=mobile&grant_type=password&scope=read,write&username=mobile&password=mobile
101 | * */
102 | public String getFullUri() {
103 | return String.format("%s?client_id=%s&client_secret=%s&grant_type=%s&scope=%s&username=%s&password=%s",
104 | accessTokenUri, clientId, clientSecret, getGrantType(), scope, username, password);
105 | }
106 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/dto/AbstractOauthDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service.dto;
2 |
3 |
4 |
5 | import org.apache.commons.lang3.StringUtils;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * @author Shengzhao Li
11 | */
12 | public abstract class AbstractOauthDto implements Serializable {
13 |
14 |
15 | private static final long serialVersionUID = -5902798061281438305L;
16 | //Error if have from oauth server
17 | protected String errorDescription;
18 | protected String error;
19 |
20 |
21 | //original data
22 | protected String originalText;
23 |
24 |
25 | protected AbstractOauthDto() {
26 | }
27 |
28 |
29 | public boolean error() {
30 | return StringUtils.isNotEmpty(error) || StringUtils.isNotEmpty(errorDescription);
31 | }
32 |
33 | public String getOriginalText() {
34 | return originalText;
35 | }
36 |
37 | public void setOriginalText(String originalText) {
38 | this.originalText = originalText;
39 | }
40 |
41 | public String getErrorDescription() {
42 | return errorDescription;
43 | }
44 |
45 | public void setErrorDescription(String errorDescription) {
46 | this.errorDescription = errorDescription;
47 | }
48 |
49 | public String getError() {
50 | return error;
51 | }
52 |
53 | public void setError(String error) {
54 | this.error = error;
55 | }
56 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/dto/AuthCallbackDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service.dto;
2 |
3 |
4 | import org.apache.commons.lang3.StringUtils;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * From spring-oauth-client(https://gitee.com/mkk/spring-oauth-client)
10 | *
11 | * @author Shengzhao Li
12 | */
13 | public class AuthCallbackDto implements Serializable {
14 |
15 |
16 | private static final long serialVersionUID = 4713732199062099307L;
17 | private String code;
18 | private String state;
19 |
20 | /*
21 | * Server response error,
22 | * For example: Click 'Deny' button
23 | * */
24 | private String error;
25 | private String error_description;
26 |
27 |
28 | public AuthCallbackDto() {
29 | }
30 |
31 | public String getError() {
32 | return error;
33 | }
34 |
35 | public boolean error() {
36 | return StringUtils.isNotEmpty(error) || StringUtils.isNotEmpty(error_description);
37 | }
38 |
39 | public void setError(String error) {
40 | this.error = error;
41 | }
42 |
43 | public String getError_description() {
44 | return error_description;
45 | }
46 |
47 | public void setError_description(String error_description) {
48 | this.error_description = error_description;
49 | }
50 |
51 | public String getCode() {
52 | return code;
53 | }
54 |
55 | public void setCode(String code) {
56 | this.code = code;
57 | }
58 |
59 | public String getState() {
60 | return state;
61 | }
62 |
63 | public void setState(String state) {
64 | this.state = state;
65 | }
66 |
67 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/dto/AuthorizationCodeDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service.dto;
2 |
3 | import java.io.Serializable;
4 | import java.io.UnsupportedEncodingException;
5 | import java.net.URLEncoder;
6 |
7 | /**
8 | * *
9 | * From spring-oauth-client(https://gitee.com/mkk/spring-oauth-client)
10 | *
11 | * @author Shengzhao Li
12 | */
13 | public class AuthorizationCodeDto implements Serializable {
14 |
15 |
16 | private static final long serialVersionUID = -5293876788733247369L;
17 | private String userAuthorizationUri;
18 | private String responseType;
19 | private String scope;
20 | private String clientId;
21 | private String redirectUri;
22 | private String state;
23 |
24 |
25 | public AuthorizationCodeDto() {
26 | }
27 |
28 |
29 | public String getUserAuthorizationUri() {
30 | return userAuthorizationUri;
31 | }
32 |
33 | public void setUserAuthorizationUri(String userAuthorizationUri) {
34 | this.userAuthorizationUri = userAuthorizationUri;
35 | }
36 |
37 | public String getResponseType() {
38 | return responseType;
39 | }
40 |
41 | public void setResponseType(String responseType) {
42 | this.responseType = responseType;
43 | }
44 |
45 | public String getScope() {
46 | return scope;
47 | }
48 |
49 | public void setScope(String scope) {
50 | this.scope = scope;
51 | }
52 |
53 | public String getClientId() {
54 | return clientId;
55 | }
56 |
57 | public void setClientId(String clientId) {
58 | this.clientId = clientId;
59 | }
60 |
61 | public String getRedirectUri() {
62 | return redirectUri;
63 | }
64 |
65 | public void setRedirectUri(String redirectUri) {
66 | this.redirectUri = redirectUri;
67 | }
68 |
69 | public String getState() {
70 | return state;
71 | }
72 |
73 | public void setState(String state) {
74 | this.state = state;
75 | }
76 |
77 | /*
78 | * http://localhost:8080/oauth/authorize?client_id=unity-client&redirect_uri=http%3a%2f%2flocalhost%3a8080%2funity%2fdashboard.htm&response_type=code&scope=read
79 | * */
80 | public String getFullUri() throws UnsupportedEncodingException {
81 | String redirect = URLEncoder.encode(redirectUri, "UTF-8");
82 | return String.format("%s?response_type=%s&scope=%s&client_id=%s&redirect_uri=%s&state=%s", userAuthorizationUri, responseType, scope, clientId, redirect, state);
83 | }
84 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/dto/RefreshAccessTokenDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service.dto;
2 |
3 | import java.io.Serializable;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | /**
8 | * http://localhost:8080/spring-oauth-server/oauth/token?client_id=mobile-client&client_secret=mobile&grant_type=refresh_token&refresh_token=b36f4978-a172-4aa8-af89-60f58abe3ba1
9 | *
10 | * @author Shengzhao Li
11 | * @since 1.1.0
12 | */
13 | public class RefreshAccessTokenDto implements Serializable {
14 |
15 | private static final long serialVersionUID = -8617579193689091944L;
16 | private String refreshAccessTokenUri;
17 | private String clientId;
18 | private String clientSecret;
19 |
20 | private String grantType = "refresh_token";
21 |
22 | private String refreshToken;
23 |
24 |
25 | public RefreshAccessTokenDto() {
26 | }
27 |
28 | public String getRefreshAccessTokenUri() {
29 | return refreshAccessTokenUri;
30 | }
31 |
32 | public void setRefreshAccessTokenUri(String refreshAccessTokenUri) {
33 | this.refreshAccessTokenUri = refreshAccessTokenUri;
34 | }
35 |
36 | public String getClientId() {
37 | return clientId;
38 | }
39 |
40 | public void setClientId(String clientId) {
41 | this.clientId = clientId;
42 | }
43 |
44 | public String getClientSecret() {
45 | return clientSecret;
46 | }
47 |
48 | public void setClientSecret(String clientSecret) {
49 | this.clientSecret = clientSecret;
50 | }
51 |
52 | public String getGrantType() {
53 | return grantType;
54 | }
55 |
56 | public void setGrantType(String grantType) {
57 | this.grantType = grantType;
58 | }
59 |
60 | public String getRefreshToken() {
61 | return refreshToken;
62 | }
63 |
64 | public void setRefreshToken(String refreshToken) {
65 | this.refreshToken = refreshToken;
66 | }
67 |
68 | /*
69 | * http://localhost:8080/spring-oauth-server/oauth/token?client_id=mobile-client&client_secret=mobile&grant_type=refresh_token&refresh_token=b36f4978-a172-4aa8-af89-60f58abe3ba1
70 | * */
71 | public Map getRefreshTokenParams() {
72 | Map map = new HashMap<>();
73 | map.put("client_id", clientId);
74 |
75 | map.put("client_secret", clientSecret);
76 | map.put("grant_type", grantType);
77 | map.put("refresh_token", refreshToken);
78 |
79 | return map;
80 | }
81 |
82 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/service/dto/UserInfoDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.service.dto;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | *
10 | * {"openid":"Ajlt9ZwVyGUvxrJCdKlFA4AataAVKVgH6gxYeCxD6J","username":"mobile","phone":null,"email":"mobile@qc8.me","create_time":0,"privileges":["USER","ADMIN","UNITY","MOBILE"]}
11 | *
12 | *
13 | * @author Shengzhao Li
14 | * @since 1.1.0
15 | */
16 | public class UserInfoDto extends AbstractOauthDto {
17 |
18 |
19 | private static final long serialVersionUID = -4028887815415395655L;
20 |
21 | @JsonProperty("create_time")
22 | private long createTime;
23 | private String email;
24 | private String openid;
25 |
26 | private String phone;
27 | private String username;
28 |
29 | private List privileges = new ArrayList<>();
30 |
31 |
32 | public UserInfoDto() {
33 | }
34 |
35 | public UserInfoDto(String error, String errorDescription) {
36 | this.error = error;
37 | this.errorDescription = errorDescription;
38 | }
39 |
40 |
41 | public long getCreateTime() {
42 | return createTime;
43 | }
44 |
45 | public void setCreateTime(long createTime) {
46 | this.createTime = createTime;
47 | }
48 |
49 | public String getOpenid() {
50 | return openid;
51 | }
52 |
53 | public void setOpenid(String openid) {
54 | this.openid = openid;
55 | }
56 |
57 | public String getEmail() {
58 | return email;
59 | }
60 |
61 | public void setEmail(String email) {
62 | this.email = email;
63 | }
64 |
65 |
66 | public String getPhone() {
67 | return phone;
68 | }
69 |
70 | public void setPhone(String phone) {
71 | this.phone = phone;
72 | }
73 |
74 | public String getUsername() {
75 | return username;
76 | }
77 |
78 | public void setUsername(String username) {
79 | this.username = username;
80 | }
81 |
82 | public List getPrivileges() {
83 | return privileges;
84 | }
85 |
86 | public void setPrivileges(List privileges) {
87 | this.privileges = privileges;
88 | }
89 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/WebUtils.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web;
2 |
3 |
4 | import org.apache.commons.lang3.StringUtils;
5 |
6 | import javax.servlet.ServletContext;
7 | import javax.servlet.http.HttpServletRequest;
8 |
9 | /**
10 | * From spring-oauth-client(https://gitee.com/mkk/spring-oauth-client)
11 | *
12 | * @author Shengzhao Li
13 | */
14 | public abstract class WebUtils {
15 |
16 |
17 | private WebUtils() {
18 | }
19 |
20 |
21 | /*
22 | * Save state to ServletContext, key = value = state
23 | */
24 | public static void saveState(HttpServletRequest request, String state) {
25 | final ServletContext servletContext = request.getSession().getServletContext();
26 | servletContext.setAttribute(state, state);
27 | }
28 |
29 | /*
30 | * Validate state when callback from Oauth Server.
31 | * If validation successful, will remove it from ServletContext.
32 | */
33 | public static boolean validateState(HttpServletRequest request, String state) {
34 | if (StringUtils.isBlank(state)) {
35 | return false;
36 | }
37 | final ServletContext servletContext = request.getSession().getServletContext();
38 | final Object value = servletContext.getAttribute(state);
39 |
40 | if (value != null) {
41 | servletContext.removeAttribute(state);
42 | return true;
43 | }
44 | return false;
45 | }
46 |
47 |
48 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/context/OIDCApplicationContextAware.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web.context;
2 |
3 |
4 | import myoidc.client.domain.shared.Application;
5 | import myoidc.client.domain.shared.BeanProvider;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.BeansException;
9 | import org.springframework.beans.factory.annotation.Value;
10 | import org.springframework.context.ApplicationContext;
11 | import org.springframework.context.ApplicationContextAware;
12 | import org.springframework.stereotype.Component;
13 |
14 | /**
15 | * 2018/03/22
16 | *
17 | *
18 | * @author Shengzhao Li
19 | */
20 | @Component
21 | public class OIDCApplicationContextAware implements ApplicationContextAware {
22 |
23 |
24 | private static final Logger LOG = LoggerFactory.getLogger(OIDCApplicationContextAware.class);
25 |
26 |
27 | @Value("${spring.application.name}")
28 | private String applicationName;
29 |
30 |
31 | @Value("${application.host}")
32 | private String applicationHost;
33 |
34 |
35 | public OIDCApplicationContextAware() {
36 | }
37 |
38 | @Override
39 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
40 | BeanProvider.initialize(applicationContext);
41 |
42 | if (LOG.isDebugEnabled()) {
43 | LOG.debug("Initialed BeanProvider from ApplicationContext: {}", applicationContext);
44 | }
45 | LOG.info("{} context initialized, Version: {}, applicationHost: {}\n", this.applicationName, Application.VERSION, this.applicationHost);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/context/OIDCServletContextAware.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web.context;
2 |
3 | import myoidc.client.domain.shared.Application;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.stereotype.Component;
7 | import org.springframework.web.context.ServletContextAware;
8 |
9 | import javax.servlet.ServletContext;
10 |
11 | /**
12 | * 2020/5/7
13 | *
14 | * @author Shengzhao Li
15 | * @since 1.1.1
16 | */
17 | @Component
18 | public class OIDCServletContextAware implements ServletContextAware {
19 |
20 | private static final Logger LOG = LoggerFactory.getLogger(OIDCServletContextAware.class);
21 |
22 | public OIDCServletContextAware() {
23 | }
24 |
25 | @Override
26 | public void setServletContext(ServletContext servletContext) {
27 |
28 | //主版本号
29 | servletContext.setAttribute("mainVersion", Application.VERSION);
30 | LOG.debug("Initialed: {}, mainVersion: {}", this, Application.VERSION);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/controller/ClientCredentialsController.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web.controller;
2 |
3 |
4 | import myoidc.client.domain.DiscoveryEndpointInfo;
5 | import myoidc.client.domain.RPHolder;
6 | import myoidc.client.service.MyOIDCClientService;
7 | import myoidc.client.service.dto.AccessTokenDto;
8 | import myoidc.client.service.dto.AuthAccessTokenDto;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Controller;
13 | import org.springframework.ui.Model;
14 | import org.springframework.web.bind.annotation.GetMapping;
15 | import org.springframework.web.bind.annotation.RequestMapping;
16 | import org.springframework.web.bind.annotation.RequestMethod;
17 | import org.springframework.web.bind.annotation.ResponseBody;
18 |
19 | import javax.servlet.http.HttpServletResponse;
20 |
21 |
22 | /**
23 | * Handle 'client_credentials' type actions
24 | *
25 | * @author Shengzhao Li
26 | * @since 1.1.0
27 | */
28 | @Controller
29 | public class ClientCredentialsController {
30 |
31 |
32 | private static final Logger LOG = LoggerFactory.getLogger(ClientCredentialsController.class);
33 |
34 |
35 | @Autowired
36 | private MyOIDCClientService clientService;
37 |
38 | /**
39 | * Entrance: step-1
40 | */
41 | @GetMapping(value = "client_credentials")
42 | public String password(Model model) {
43 | RPHolder rpHoldDto = clientService.loadRPHolder();
44 | //异常跳转回主页
45 | if (!rpHoldDto.isConfigRP()) {
46 | return "redirect:/";
47 | }
48 | DiscoveryEndpointInfo endpointInfo = rpHoldDto.getDiscoveryEndpointInfo();
49 | LOG.debug("Go to 'client_credentials' page, accessTokenUri = {}", endpointInfo.getToken_endpoint());
50 | model.addAttribute("rpHoldDto", rpHoldDto);
51 | model.addAttribute("endpointInfo", endpointInfo);
52 | return "client_credentials";
53 | }
54 |
55 |
56 | /**
57 | * Ajax call , get access_token
58 | */
59 | @GetMapping(value = "credentials_access_token")
60 | @ResponseBody
61 | public AccessTokenDto getAccessToken(AuthAccessTokenDto authAccessTokenDto) {
62 | return clientService.retrieveCredentialsAccessTokenDto(authAccessTokenDto);
63 | }
64 |
65 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/controller/ImplicitController.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web.controller;
2 |
3 | import myoidc.client.domain.DiscoveryEndpointInfo;
4 | import myoidc.client.domain.RPHolder;
5 | import myoidc.client.domain.shared.Application;
6 | import myoidc.client.service.MyOIDCClientService;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.stereotype.Controller;
11 | import org.springframework.ui.Model;
12 | import org.springframework.web.bind.annotation.GetMapping;
13 |
14 | /**
15 | * Handle 'implicit' type actions
16 | *
17 | * @author Shengzhao Li
18 | * @since 1.1.0
19 | */
20 | @Controller
21 | public class ImplicitController {
22 |
23 |
24 | private static final Logger LOG = LoggerFactory.getLogger(ImplicitController.class);
25 |
26 |
27 | @Autowired
28 | private MyOIDCClientService clientService;
29 |
30 |
31 | /**
32 | * Entrance: step-1
33 | */
34 | @GetMapping(value = "implicit")
35 | public String password(Model model) {
36 | RPHolder rpHoldDto = clientService.loadRPHolder();
37 | //异常跳转回主页
38 | if (!rpHoldDto.isConfigRP()) {
39 | return "redirect:/";
40 | }
41 | DiscoveryEndpointInfo endpointInfo = rpHoldDto.getDiscoveryEndpointInfo();
42 | LOG.debug("Go to 'implicit' page: {}",endpointInfo);
43 | model.addAttribute("rpHoldDto", rpHoldDto);
44 | model.addAttribute("endpointInfo", endpointInfo);
45 | // model.addAttribute("userAuthorizationUri", userAuthorizationUri);
46 | // model.addAttribute("unityUserInfoUri", unityUserInfoUri);
47 | model.addAttribute("host", Application.host());
48 | return "implicit";
49 | }
50 |
51 |
52 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/controller/PasswordController.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web.controller;
2 |
3 | import myoidc.client.domain.DiscoveryEndpointInfo;
4 | import myoidc.client.domain.RPHolder;
5 | import myoidc.client.service.MyOIDCClientService;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.ui.Model;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 |
13 | /**
14 | * Handle 'password' type actions
15 | * From spring-oauth-client(https://gitee.com/mkk/spring-oauth-client)
16 | *
17 | * @author Shengzhao Li
18 | * @since 1.1.0
19 | */
20 | @Controller
21 | public class PasswordController {
22 |
23 |
24 | private static final Logger LOG = LoggerFactory.getLogger(PasswordController.class);
25 |
26 |
27 | @Autowired
28 | private MyOIDCClientService clientService;
29 |
30 |
31 | /**
32 | * Entrance: step-1
33 | */
34 | @GetMapping(value = "password")
35 | public String password(Model model) {
36 | RPHolder rpHoldDto = clientService.loadRPHolder();
37 | //异常跳转回主页
38 | if (!rpHoldDto.isConfigRP()) {
39 | return "redirect:/";
40 | }
41 | DiscoveryEndpointInfo endpointInfo = rpHoldDto.getDiscoveryEndpointInfo();
42 | LOG.debug("Go to 'password' page, accessTokenUri = {}", endpointInfo.getToken_endpoint());
43 | model.addAttribute("accessTokenUri", endpointInfo.getToken_endpoint());
44 | model.addAttribute("rpHoldDto", rpHoldDto);
45 | return "password";
46 | }
47 |
48 |
49 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/controller/RefreshTokenController.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web.controller;
2 |
3 |
4 | import myoidc.client.domain.DiscoveryEndpointInfo;
5 | import myoidc.client.domain.RPHolder;
6 | import myoidc.client.service.MyOIDCClientService;
7 | import myoidc.client.service.dto.AccessTokenDto;
8 | import myoidc.client.service.dto.AuthAccessTokenDto;
9 | import myoidc.client.service.dto.RefreshAccessTokenDto;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.stereotype.Controller;
14 | import org.springframework.ui.Model;
15 | import org.springframework.web.bind.annotation.GetMapping;
16 | import org.springframework.web.bind.annotation.ResponseBody;
17 |
18 |
19 | /**
20 | * Handle 'refresh_token' type actions
21 | * From spring-oauth-client(https://gitee.com/mkk/spring-oauth-client)
22 | *
23 | * @author Shengzhao Li
24 | * @since 1.1.0
25 | */
26 | @Controller
27 | public class RefreshTokenController {
28 |
29 |
30 | private static final Logger LOG = LoggerFactory.getLogger(RefreshTokenController.class);
31 |
32 |
33 | @Autowired
34 | private MyOIDCClientService clientService;
35 |
36 | /**
37 | * Entrance: step-1
38 | */
39 | @GetMapping(value = "refresh_token")
40 | public String refresh(Model model) {
41 | RPHolder rpHoldDto = clientService.loadRPHolder();
42 | //异常跳转回主页
43 | if (!rpHoldDto.isConfigRP()) {
44 | return "redirect:/";
45 | }
46 | DiscoveryEndpointInfo endpointInfo = rpHoldDto.getDiscoveryEndpointInfo();
47 | LOG.debug("Go to 'refresh_token' page, DiscoveryEndpointInfo = {}", endpointInfo);
48 | model.addAttribute("rpHoldDto", rpHoldDto);
49 | model.addAttribute("endpointInfo", endpointInfo);
50 | return "refresh_token";
51 | }
52 |
53 | /**
54 | * Ajax call , get access_token
55 | */
56 | @GetMapping(value = "password_access_token")
57 | @ResponseBody
58 | public AccessTokenDto getAccessToken(AuthAccessTokenDto authAccessTokenDto) {
59 | return clientService.retrievePasswordAccessTokenDto(authAccessTokenDto);
60 | }
61 |
62 | /**
63 | * Ajax call , refresh access_token
64 | */
65 | @GetMapping(value = "refresh_access_token")
66 | @ResponseBody
67 | public AccessTokenDto refreshAccessToken(RefreshAccessTokenDto refreshAccessTokenDto) {
68 | return clientService.refreshAccessTokenDto(refreshAccessTokenDto);
69 | }
70 |
71 |
72 | }
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/controller/StartupController.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web.controller;
2 |
3 |
4 | import myoidc.client.domain.shared.Application;
5 | import myoidc.client.service.MyOIDCClientService;
6 | import myoidc.client.domain.RPHolder;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.stereotype.Controller;
11 | import org.springframework.ui.Model;
12 | import org.springframework.validation.BindingResult;
13 | import org.springframework.web.bind.annotation.*;
14 |
15 | import javax.validation.Valid;
16 | import java.util.Map;
17 |
18 |
19 | /**
20 | * 2018/2/5
21 | *
22 | * 引导 入口
23 | *
24 | * @author Shengzhao Li
25 | */
26 | @Controller
27 | public class StartupController {
28 |
29 |
30 | private static final Logger LOG = LoggerFactory.getLogger(StartupController.class);
31 |
32 |
33 | @Autowired
34 | private MyOIDCClientService clientService;
35 |
36 | /**
37 | * 首页
38 | */
39 | @GetMapping("/")
40 | public String index(Model model) {
41 | RPHolder rpHoldDto = clientService.loadRPHolder();
42 | model.addAttribute("host", Application.host());
43 | model.addAttribute("formDto", rpHoldDto);
44 | return "index";
45 | }
46 |
47 | /**
48 | * submit
49 | * 提交RP信息
50 | *
51 | * @since 1.1.0
52 | */
53 | @PostMapping("/submit")
54 | public String submit(@ModelAttribute("formDto") @Valid RPHolder formDto, BindingResult result, Model model) {
55 | if (result.hasErrors()) {
56 | return "index";
57 | }
58 | boolean ok = clientService.saveRPHolder(formDto);
59 | model.addAttribute("saveResult", ok);
60 | return "redirect:/";
61 | }
62 |
63 |
64 | /**
65 | * Common handle oauth error ,
66 | * show the error message.
67 | *
68 | * @since 1..1.0
69 | */
70 | @RequestMapping("oauth_error")
71 | public String oauthError(String error, String message, Model model) {
72 | model.addAttribute("error", error);
73 | model.addAttribute("message", message);
74 |
75 | LOG.debug("Go to oauth_error, error={},message={}", error, message);
76 | return "oauth_error";
77 | }
78 |
79 |
80 | /**
81 | * verify id_token
82 | *
83 | * @param token token
84 | * @return map
85 | * @since 1.1.0
86 | */
87 | @GetMapping("verify_token")
88 | @ResponseBody
89 | public Map verifyIdToken(@RequestParam String token) {
90 | return clientService.verifyToken(token);
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/java/myoidc/client/web/controller/UserInfoController.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.web.controller;
2 |
3 | import myoidc.client.service.MyOIDCClientService;
4 | import myoidc.client.service.dto.UserInfoDto;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.ui.Model;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 |
10 | /**
11 | * 2020/4/11
12 | *
13 | * @author Shengzhao Li
14 | * @since 1.1.0
15 | */
16 | @Controller
17 | public class UserInfoController {
18 |
19 |
20 | @Autowired
21 | private MyOIDCClientService clientService;
22 |
23 |
24 | /**
25 | * user_info API
26 | */
27 | @GetMapping("user_info")
28 | public String unityUserInfo(String access_token, Model model) {
29 | UserInfoDto userDto = clientService.loadUserInfoDto(access_token);
30 |
31 | if (userDto.error()) {
32 | //error
33 | model.addAttribute("message", userDto.getErrorDescription());
34 | model.addAttribute("error", userDto.getError());
35 | return "redirect:oauth_error";
36 | } else {
37 | model.addAttribute("userDto", userDto);
38 | return "user_info";
39 | }
40 |
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | # MyOIDC -Client V-1.1.0
2 | #
3 | spring.application.name=MyOIDC[Client]
4 | spring.main.allow-bean-definition-overriding=true
5 | spring.jmx.enabled=false
6 | #
7 | #
8 | # MVC
9 | spring.mvc.ignore-default-model-on-redirect=false
10 | spring.http.encoding.enabled=true
11 | spring.http.encoding.charset=UTF-8
12 | spring.http.encoding.force=true
13 | #
14 | #THYMELEAF (ThymeleafAutoConfiguration)
15 | #
16 | #spring.thymeleaf.prefix=/WEB-INF/view/
17 | #spring.thymeleaf.suffix=.html
18 | #spring.thymeleaf.mode=HTML5
19 | spring.thymeleaf.encoding=UTF-8
20 | # ;charset= is added
21 | # set to false for hot refresh
22 | spring.thymeleaf.cache=false
23 | #
24 | # Logging INFO
25 | #
26 | logging.level.root=INFO
27 | #logging.config=classpath:log4j2.xml
28 | #logging.level.org.springframework.transaction.interceptor=TRACE
29 | #
30 | # Security
31 | #
32 | #
33 | #Tomcat Server Config
34 | #
35 | server.tomcat.accesslog.enabled=true
36 | server.tomcat.uri-encoding=UTF-8
37 | server.port=8087
38 | #
39 | # gzip, compression
40 | server.compression.enabled=true
41 | server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
42 | server.compression.min-response-size=1024
43 | #
44 | #Application host url, end by '/'
45 | application.host=http://localhost:${server.port}/
46 |
47 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/static/bootstrap/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-client/src/main/resources/static/bootstrap/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/static/bootstrap/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-client/src/main/resources/static/bootstrap/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/static/bootstrap/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-client/src/main/resources/static/bootstrap/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/static/bootstrap/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-client/src/main/resources/static/bootstrap/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-client/src/main/resources/static/favicon.ico
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/templates/error/405.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Error-405 . MyOIDC[RP]
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
405
17 |
18 | Method Not Allowed
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/templates/fragment/footer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Fragment Footer
6 |
7 |
8 |
9 |
10 |
11 |
© 2017-2020 MyOIDC
13 | V
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/templates/fragment/header.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | Fragment Header
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/templates/oauth_error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | OAuth2 Error . MyOIDC[RP]
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
OAuth2 Error
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/myoidc-client/src/main/resources/templates/user_info.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | User Info . MyOIDC[RP]
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
User Info
18 | 数据来源于 'myoidc-server' 中提供的User Info API接口
19 |
20 |
21 |
22 | - username
23 | user1
24 | - openid
25 | oows
26 | - phone
27 | se
28 | - email
29 | sz
30 | - privileges
31 |
32 | - createTime
33 |
34 |
35 |
36 |
37 |
Back
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/myoidc-client/src/test/java/myoidc/client/MyOIDCClientApplicationTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.client;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.TestPropertySource;
7 | import org.springframework.test.context.junit4.SpringRunner;
8 |
9 | import static org.junit.Assert.*;
10 |
11 | /**
12 | * 2018/5/26
13 | *
14 | * @author Shengzhao Li
15 | */
16 | @RunWith(SpringRunner.class)
17 | @SpringBootTest
18 | @TestPropertySource(locations = "classpath:application-test.properties")
19 | public class MyOIDCClientApplicationTest {
20 |
21 |
22 |
23 | @Test
24 | public void contextLoads() {
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/myoidc-client/src/test/java/myoidc/client/domain/DiscoveryEndpointInfoTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.domain;
2 |
3 | import org.junit.Ignore;
4 | import org.junit.Test;
5 | import org.springframework.web.client.RestTemplate;
6 |
7 | import static org.junit.Assert.*;
8 |
9 | /**
10 | * 2020/4/7
11 | *
12 | * @author Shengzhao Li
13 | * @since 1.1.0
14 | */
15 | public class DiscoveryEndpointInfoTest {
16 |
17 |
18 | @Test
19 | @Ignore
20 | public void test() {
21 |
22 | RestTemplate restTemplate = new RestTemplate();
23 | DiscoveryEndpointInfo info = restTemplate.getForObject("http://localhost:8080/myoidc-server/.well-known/openid-configuration", DiscoveryEndpointInfo.class);
24 |
25 | assertNotNull(info);
26 |
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/myoidc-client/src/test/java/myoidc/client/infrastructure/RPHolderRepositoryDefaultTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.client.infrastructure;
2 |
3 | import myoidc.client.domain.RPHolder;
4 | import org.junit.Ignore;
5 | import org.junit.Test;
6 |
7 | import static org.junit.Assert.*;
8 |
9 | /**
10 | * 2020/4/7
11 | *
12 | * @author Shengzhao Li
13 | */
14 | public class RPHolderRepositoryDefaultTest {
15 |
16 |
17 | private RPHolderRepositoryDefault repositoryDefault = new RPHolderRepositoryDefault();
18 |
19 |
20 | @Test
21 | @Ignore
22 | public void test() {
23 |
24 |
25 | RPHolder rpHolder = repositoryDefault.findRPHolder();
26 | assertNotNull(rpHolder);
27 | // assertFalse(rpHolder.isConfigRP());
28 |
29 |
30 | rpHolder = new RPHolder();
31 | rpHolder.setClientId("clientId");
32 | rpHolder.setClientSecret("clientSecret");
33 | rpHolder.setDiscoveryEndpoint("https://...");
34 |
35 | boolean ok = repositoryDefault.saveRPHolder(rpHolder);
36 | assertTrue(ok);
37 |
38 | }
39 | }
--------------------------------------------------------------------------------
/myoidc-client/src/test/resources/application-test.properties:
--------------------------------------------------------------------------------
1 | # MyOIDC -Client V-1.1.0
2 | #
3 | spring.application.name=MyOIDC[Client]
4 | #
5 | #
6 | # MVC
7 | spring.mvc.ignore-default-model-on-redirect=false
8 | spring.http.encoding.enabled=true
9 | spring.http.encoding.charset=UTF-8
10 | spring.http.encoding.force=true
11 | #
12 | #THYMELEAF (ThymeleafAutoConfiguration)
13 | #
14 | spring.thymeleaf.prefix=/WEB-INF/view/
15 | spring.thymeleaf.suffix=.html
16 | #spring.thymeleaf.mode=HTML5
17 | spring.thymeleaf.encoding=UTF-8
18 | # ;charset= is added
19 | # set to false for hot refresh
20 | spring.thymeleaf.cache=false
21 | #
22 | # Logging INFO
23 | #
24 | logging.level.root=INFO
25 | #logging.config=classpath:log4j2.xml
26 | #logging.level.org.springframework.transaction.interceptor=TRACE
27 | #
28 | # Security
29 | #
30 | #
31 | #Tomcat Server Config
32 | #
33 | server.tomcat.accesslog.enabled=true
34 | server.tomcat.uri-encoding=UTF-8
35 | server.port=8080
36 | #
37 | # gzip, compression
38 | server.compression.enabled=true
39 | server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
40 | server.compression.min-response-size=1024
41 | #
42 | #Application host url, end by '/'
43 | application.host=http://localhost:8080/myoidc-client/
44 |
45 |
--------------------------------------------------------------------------------
/myoidc-server/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-server/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/myoidc-server/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip
2 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/Constants.java:
--------------------------------------------------------------------------------
1 | package myoidc.server;
2 |
3 | import org.jose4j.jwk.JsonWebKey;
4 | import org.jose4j.jwk.Use;
5 | import org.jose4j.jws.AlgorithmIdentifiers;
6 |
7 | /**
8 | * 2020/3/11
9 | *
10 | * @author Shengzhao Li
11 | * @since 1.1.0
12 | */
13 | public interface Constants {
14 |
15 | /*Fixed, resource-id */
16 | String RESOURCE_ID = "myoidc-resource";
17 |
18 | /**
19 | * Fixed keyId
20 | *
21 | * @since 1.1.0
22 | */
23 | String DEFAULT_KEY_ID = "myoidc-keyid";
24 |
25 | /**
26 | * 长度 至少 1024, 建议 2048
27 | *
28 | * @since 1.1.0
29 | */
30 | int DEFAULT_KEY_SIZE = 2048;
31 |
32 |
33 | /**
34 | * keystore file name
35 | *
36 | * @since 1.1.0
37 | */
38 | String KEYSTORE_NAME = "jwks.json";
39 |
40 | /**
41 | * Default ALG: RS256
42 | *
43 | * @since 1.1.0
44 | */
45 | String OIDC_ALG = AlgorithmIdentifiers.RSA_USING_SHA256;
46 |
47 | /**
48 | * OIDC key use: sig or enc
49 | *
50 | * @since 1.1.0
51 | */
52 | String USE_SIG = Use.SIGNATURE;
53 | String USE_ENC = Use.ENCRYPTION;
54 |
55 | /**
56 | * id_token constants
57 | *
58 | * @since 1.1.0
59 | */
60 | String ID_TOKEN = "id_token";
61 |
62 | /**
63 | * JWT keyid
64 | *
65 | * @since 1.1.0
66 | */
67 | String KEY_ID = JsonWebKey.KEY_ID_PARAMETER;
68 |
69 |
70 | //系统字符编码
71 | String ENCODING = "UTF-8";
72 |
73 | String PROJECT_HOME = "https://github.com/monkeyk/MyOIDC";
74 |
75 | //Current version
76 | String VERSION = "1.1.1";
77 |
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/MyOIDCServerApplication.java:
--------------------------------------------------------------------------------
1 | package myoidc.server;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * Spring Boot bootstrap
8 | */
9 | @SpringBootApplication
10 | public class MyOIDCServerApplication {
11 |
12 |
13 | /**
14 | * Run it directly
15 | *
16 | * @param args args
17 | */
18 | public static void main(String[] args) {
19 | SpringApplication.run(MyOIDCServerApplication.class, args);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/config/MVCConfiguration.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.config;
2 |
3 |
4 | import myoidc.server.domain.shared.Application;
5 | import myoidc.server.web.filter.ExtCharacterEncodingFilter;
6 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.http.converter.HttpMessageConverter;
10 | import org.springframework.http.converter.StringHttpMessageConverter;
11 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
12 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
13 |
14 | import javax.servlet.Filter;
15 | import java.nio.charset.Charset;
16 | import java.util.List;
17 |
18 | /**
19 | * 2018/1/30
20 | *
21 | * Spring MVC 扩展配置
22 | *
23 | *
24 | * @author Shengzhao Li
25 | */
26 | @Configuration
27 | public class MVCConfiguration implements WebMvcConfigurer {
28 |
29 |
30 | /**
31 | * 扩展拦截器
32 | */
33 | @Override
34 | public void addInterceptors(InterceptorRegistry registry) {
35 |
36 | WebMvcConfigurer.super.addInterceptors(registry);
37 | }
38 |
39 |
40 | /**
41 | * 字符编码配置 UTF-8
42 | */
43 | @Bean
44 | public FilterRegistrationBean encodingFilter() {
45 | FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
46 | registrationBean.setFilter(new ExtCharacterEncodingFilter());
47 | registrationBean.addUrlPatterns("/*");
48 | return registrationBean;
49 | }
50 |
51 |
52 | /**
53 | * 解决乱码问题
54 | * For UTF-8
55 | */
56 | @Override
57 | public void configureMessageConverters(List> converters) {
58 | WebMvcConfigurer.super.configureMessageConverters(converters);
59 | converters.add(new StringHttpMessageConverter(Charset.forName(Application.ENCODING)));
60 | }
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/config/MyOIDCConfiguration.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.config;
2 |
3 |
4 | import myoidc.server.domain.shared.Application;
5 | import org.hibernate.SessionFactory;
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.orm.hibernate5.HibernateTransactionManager;
10 | import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
11 | import org.springframework.transaction.PlatformTransactionManager;
12 | import org.springframework.transaction.annotation.EnableTransactionManagement;
13 |
14 | import javax.sql.DataSource;
15 | import java.util.Properties;
16 |
17 |
18 | /**
19 | * 2018/1/30
20 | *
21 | *
22 | * @author Shengzhao Li
23 | */
24 | @Configuration
25 | @EnableTransactionManagement
26 | public class MyOIDCConfiguration {
27 |
28 |
29 | @Value("${application.host}")
30 | private String host;
31 |
32 |
33 | // Application
34 | @Bean
35 | public Application application() {
36 | Application application = new Application();
37 | application.setHost(host);
38 | return application;
39 | }
40 |
41 |
42 |
43 | @Bean
44 | public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
45 | LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
46 | factoryBean.setDataSource(dataSource);
47 | factoryBean.setPackagesToScan("myoidc.server.domain");
48 |
49 | Properties properties = new Properties();
50 | properties.setProperty("hibernate.show_sql", "false");
51 | properties.setProperty("jdbc.use_scrollable_resultset", "false");
52 | properties.setProperty("hibernate.query.substitutions", "true=1,false=0");
53 | properties.setProperty("hibernate.dialect","org.hibernate.dialect.MySQL57Dialect");
54 | properties.setProperty("hibernate.current_session_context_class", "org.springframework.orm.hibernate5.SpringSessionContext");
55 | factoryBean.setHibernateProperties(properties);
56 |
57 | return factoryBean;
58 | }
59 |
60 |
61 | @Bean
62 | public PlatformTransactionManager transactionManager(SessionFactory sessionFactory) {
63 | HibernateTransactionManager transactionManager = new HibernateTransactionManager();
64 | transactionManager.setSessionFactory(sessionFactory);
65 | return transactionManager;
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/config/OAuth2MethodSecurityConfiguration.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.config;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
5 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
6 | import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
7 | import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
8 |
9 | /**
10 | * 2018/3/22
11 | *
12 | * @author Shengzhao Li
13 | */
14 | @Configuration
15 | @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
16 | public class OAuth2MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
17 |
18 |
19 | @Override
20 | protected MethodSecurityExpressionHandler createExpressionHandler() {
21 | return new OAuth2MethodSecurityExpressionHandler();
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/AbstractDomain.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain;
2 |
3 |
4 | import myoidc.server.domain.shared.UUIDGenerator;
5 |
6 | import javax.persistence.*;
7 | import java.io.Serializable;
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * @author Shengzhao Li
12 | */
13 | @MappedSuperclass
14 | public abstract class AbstractDomain implements Serializable {
15 |
16 | private static final long serialVersionUID = 913921286328215144L;
17 | /**
18 | * Database id
19 | */
20 | @Id
21 | @GeneratedValue(strategy = GenerationType.IDENTITY)
22 | @Column(name = "id")
23 | protected int id;
24 |
25 | @Column(name = "archived", columnDefinition = "tinyint(1)")
26 | protected boolean archived;
27 |
28 | /**
29 | * 乐观锁
30 | */
31 | @Version
32 | @Column(name = "version")
33 | protected int version;
34 |
35 | /**
36 | * Domain business uuid.
37 | */
38 | @Column(name = "uuid", unique = true)
39 | protected String uuid = UUIDGenerator.generate();
40 |
41 | /**
42 | * The domain create time.
43 | */
44 | @Column(name = "create_time")
45 | // @Type(type = "org.hibernate.type.LocalDateTimeType")
46 | protected LocalDateTime createTime = LocalDateTime.now();
47 |
48 |
49 | public AbstractDomain() {
50 | }
51 |
52 | public int id() {
53 | return id;
54 | }
55 |
56 | public void id(int id) {
57 | this.id = id;
58 | }
59 |
60 | public boolean archived() {
61 | return archived;
62 | }
63 |
64 | public AbstractDomain archived(boolean archived) {
65 | this.archived = archived;
66 | return this;
67 | }
68 |
69 | public String uuid() {
70 | return uuid;
71 | }
72 |
73 | public void uuid(String uuid) {
74 | this.uuid = uuid;
75 | }
76 |
77 | public LocalDateTime createTime() {
78 | return createTime;
79 | }
80 |
81 | public boolean isNewly() {
82 | return id == 0;
83 | }
84 |
85 | @Override
86 | public boolean equals(Object o) {
87 | if (this == o) {
88 | return true;
89 | }
90 | if (!(o instanceof AbstractDomain)) {
91 | return false;
92 | }
93 | AbstractDomain that = (AbstractDomain) o;
94 | return uuid.equals(that.uuid);
95 | }
96 |
97 | @Override
98 | public int hashCode() {
99 | return uuid.hashCode();
100 | }
101 |
102 |
103 | @Override
104 | public String toString() {
105 | final StringBuilder sb = new StringBuilder();
106 | sb.append("{id=").append(id);
107 | sb.append(", archived=").append(archived);
108 | sb.append(", version=").append(version);
109 | sb.append(", uuid='").append(uuid).append('\'');
110 | sb.append(", createTime=").append(createTime);
111 | sb.append('}');
112 | return sb.toString();
113 | }
114 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/README.txt:
--------------------------------------------------------------------------------
1 |
2 | All Domain, shared in Here
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/oauth/OauthRepository.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.oauth;
2 |
3 |
4 | import java.util.List;
5 |
6 | /**
7 | * 处理 OAuth 相关业务的 Repository
8 | *
9 | * @author Shengzhao Li
10 | */
11 | public interface OauthRepository {
12 |
13 | OauthClientDetails findOauthClientDetails(String clientId);
14 |
15 | List findAllOauthClientDetails(String clientId);
16 |
17 | int updateOauthClientDetailsArchive(String clientId, boolean archive);
18 |
19 | void saveOauthClientDetails(OauthClientDetails clientDetails);
20 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/security/OIDCUserDetails.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.security;
2 |
3 |
4 | import myoidc.server.domain.user.Privilege;
5 | import myoidc.server.domain.user.User;
6 | import org.springframework.security.core.GrantedAuthority;
7 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
8 | import org.springframework.security.core.userdetails.UserDetails;
9 |
10 | import java.util.ArrayList;
11 | import java.util.Arrays;
12 | import java.util.Collection;
13 | import java.util.List;
14 |
15 | /**
16 | * @author Shengzhao Li
17 | */
18 | public class OIDCUserDetails implements UserDetails {
19 |
20 |
21 | protected static final String ROLE_PREFIX = "ROLE_";
22 | private static final long serialVersionUID = 5161957098952238466L;
23 |
24 | protected User user;
25 |
26 | protected List authorities = new ArrayList<>();
27 |
28 | public OIDCUserDetails() {
29 | }
30 |
31 | public OIDCUserDetails(User user) {
32 | this.user = user;
33 | initialPrivileges();
34 | }
35 |
36 | private void initialPrivileges() {
37 | List privilegeList = privilegeList();
38 | for (Privilege privilege : privilegeList) {
39 | this.authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + privilege.name()));
40 | }
41 | }
42 |
43 | private List privilegeList() {
44 | //defaultUser 有所有权限
45 | if (user.defaultUser()) {
46 | return Arrays.asList(Privilege.values());
47 | } else {
48 | //固定值
49 | final List privileges = user.privileges();
50 | privileges.add(Privilege.USER);
51 | return privileges;
52 | }
53 | }
54 |
55 | @Override
56 | public Collection extends GrantedAuthority> getAuthorities() {
57 | return authorities;
58 | }
59 |
60 | @Override
61 | public String getPassword() {
62 | return user.password();
63 | }
64 |
65 | @Override
66 | public String getUsername() {
67 | return user.username();
68 | }
69 |
70 | @Override
71 | public boolean isAccountNonExpired() {
72 | return true;
73 | }
74 |
75 | @Override
76 | public boolean isAccountNonLocked() {
77 | return true;
78 | }
79 |
80 | @Override
81 | public boolean isCredentialsNonExpired() {
82 | return true;
83 | }
84 |
85 | @Override
86 | public boolean isEnabled() {
87 | return true;
88 | }
89 |
90 | public User user() {
91 | return user;
92 | }
93 |
94 |
95 | @Override
96 | public String toString() {
97 | return "{" +
98 | "user=" + user +
99 | ", authorities=" + authorities +
100 | '}';
101 | }
102 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/security/SecurityHolder.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.security;
2 |
3 | /**
4 | * @author Shengzhao Li
5 | */
6 |
7 | public interface SecurityHolder {
8 |
9 | OIDCUserDetails userDetails();
10 |
11 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/security/SecurityUtils.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.security;
2 |
3 |
4 | import myoidc.server.domain.user.User;
5 |
6 | /**
7 | * @author Shengzhao Li
8 | */
9 | public class SecurityUtils {
10 |
11 | private static SecurityHolder securityHolder;
12 |
13 | public void setSecurityHolder(SecurityHolder securityHolder) {
14 | SecurityUtils.securityHolder = securityHolder;
15 | }
16 |
17 |
18 | /**
19 | * 当前登录用户
20 | *
21 | * @return Current user
22 | * @since 1.1.0
23 | */
24 | public static User currentUser() {
25 | OIDCUserDetails userDetails = securityHolder.userDetails();
26 | return userDetails != null ? userDetails.user() : null;
27 | }
28 |
29 |
30 | /**
31 | * 当前登录用户名
32 | *
33 | * @return Current username
34 | * @since 1.1.0
35 | */
36 | public static String currentUsername() {
37 | final User user = currentUser();
38 | return user != null ? user.username() : "unknown";
39 | }
40 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/shared/Application.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.shared;
2 |
3 |
4 | import myoidc.server.Constants;
5 | import org.springframework.beans.factory.InitializingBean;
6 | import org.springframework.util.Assert;
7 |
8 | /**
9 | * @author Shengzhao Li
10 | */
11 | public class Application implements InitializingBean, Constants {
12 |
13 |
14 | //application host
15 | private static String host;
16 |
17 |
18 | /*
19 | * default
20 | * */
21 | public Application() {
22 | }
23 |
24 |
25 | public static String host() {
26 | return host;
27 | }
28 |
29 | public void setHost(String host) {
30 | Application.host = host.endsWith("/") ? host : host + "/";
31 | }
32 |
33 |
34 | @Override
35 | public void afterPropertiesSet() throws Exception {
36 | Assert.notNull(host, "host is null");
37 | }
38 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/shared/BeanProvider.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.shared;
2 |
3 | import org.springframework.context.ApplicationContext;
4 |
5 | /**
6 | * @author Shengzhao Li
7 | */
8 | public abstract class BeanProvider {
9 |
10 | private static ApplicationContext applicationContext;
11 |
12 | protected BeanProvider() {
13 | }
14 |
15 | public static void initialize(ApplicationContext applicationContext) {
16 | BeanProvider.applicationContext = applicationContext;
17 | }
18 |
19 | /**
20 | * Get Bean by clazz.
21 | *
22 | * @param clazz Class
23 | * @param class type
24 | * @return Bean instance
25 | */
26 | public static T getBean(Class clazz) {
27 | if (applicationContext == null) {
28 | return null;
29 | }
30 | return applicationContext.getBean(clazz);
31 | }
32 |
33 | @SuppressWarnings("unchecked")
34 | public static T getBean(String beanId) {
35 | if (applicationContext == null) {
36 | return null;
37 | }
38 | return (T) applicationContext.getBean(beanId);
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/shared/Repository.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.shared;
2 |
3 |
4 | import myoidc.server.domain.AbstractDomain;
5 |
6 | import java.util.Collection;
7 | import java.util.List;
8 |
9 | /**
10 | * @author Shengzhao Li
11 | */
12 |
13 | public interface Repository {
14 |
15 | T findById(Integer id, Class clazz);
16 |
17 | T findByUuid(Class clazz, String uuid);
18 |
19 | void saveOrUpdate(T domain);
20 |
21 | void saveOrUpdateAll(Collection collection);
22 |
23 | void delete(T domain);
24 |
25 | void deleteByUuid(Class clazz, String uuid);
26 |
27 | void deleteAll(Collection elements);
28 |
29 | List findAll(Class clazz, boolean active);
30 |
31 | List findByUuids(Class clazz, List uuids);
32 |
33 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/shared/UUIDGenerator.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.shared;
2 |
3 |
4 | import org.apache.commons.lang3.RandomStringUtils;
5 |
6 | /**
7 | * @author Shengzhao Li
8 | */
9 | public abstract class UUIDGenerator {
10 |
11 |
12 | protected UUIDGenerator() {
13 | }
14 |
15 |
16 | public static String generate() {
17 | return RandomStringUtils.random(42, true, true);
18 | }
19 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/user/Privilege.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.user;
2 |
3 |
4 | /**
5 | * @author Shengzhao Li
6 | */
7 |
8 | public enum Privilege {
9 |
10 | //Any user have the default privilege
11 | USER("User"),
12 |
13 | ADMIN("Admin"), //管理 权限
14 |
15 | CLIENT("Client"), //注册 client
16 | UNITY("Unity"), //资源 权限
17 | MOBILE("Mobile"); //资源 权限
18 |
19 |
20 | private String label;
21 |
22 |
23 | Privilege(String label) {
24 | this.label = label;
25 | }
26 |
27 | public String getLabel() {
28 | return label;
29 | }
30 |
31 |
32 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/user/UserPrivilege.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.user;
2 |
3 |
4 |
5 | import myoidc.server.domain.AbstractDomain;
6 |
7 | import javax.persistence.*;
8 |
9 | /**
10 | * @author Shengzhao Li
11 | */
12 | @Entity
13 | @Table(name = "user_privilege")
14 | public class UserPrivilege extends AbstractDomain {
15 |
16 | private static final long serialVersionUID = -7207158121413995079L;
17 | @ManyToOne
18 | @JoinColumn(name = "user_id")
19 | private User user;
20 |
21 | @Column(name = "privilege")
22 | @Enumerated(value = EnumType.STRING)
23 | private Privilege privilege;
24 |
25 | public UserPrivilege() {
26 | }
27 |
28 | public UserPrivilege(User user, Privilege privilege) {
29 | this.user = user;
30 | this.privilege = privilege;
31 | }
32 |
33 | public Privilege privilege() {
34 | return privilege;
35 | }
36 |
37 | public User user() {
38 | return user;
39 | }
40 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/domain/user/UserRepository.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.user;
2 |
3 |
4 | import myoidc.server.domain.shared.Repository;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author Shengzhao Li
10 | */
11 |
12 | public interface UserRepository extends Repository {
13 |
14 |
15 | User findLoginUserByUsername(String username);
16 |
17 | List findUserPrivileges(String userUuid);
18 |
19 | List findUsersByUsername(String username);
20 |
21 | /**
22 | * 无 archived 条件
23 | *
24 | * @param username username
25 | * @return User
26 | * @since 1.1.1
27 | */
28 | User findUserByUsernameNoArchived(String username);
29 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/infrastructure/PasswordHandler.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 | import myoidc.server.domain.shared.BeanProvider;
4 | import org.apache.commons.lang3.RandomStringUtils;
5 | import org.springframework.security.crypto.password.PasswordEncoder;
6 | import org.springframework.util.Assert;
7 |
8 | /**
9 | * 2016/3/25
10 | *
11 | * From spring-oauth-server
12 | *
13 | * @author Shengzhao Li
14 | */
15 | public abstract class PasswordHandler {
16 |
17 |
18 | // private PasswordEncoder passwordEncoder = SOSContextHolder.getBean(PasswordEncoder.class);
19 |
20 |
21 | private PasswordHandler() {
22 | }
23 |
24 |
25 | public static String encode(String password) {
26 | PasswordEncoder passwordEncoder = BeanProvider.getBean(PasswordEncoder.class);
27 | Assert.notNull(passwordEncoder, "passwordEncoder is null");
28 | // BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
29 | return passwordEncoder.encode(password);
30 | }
31 |
32 |
33 | /**
34 | * 生成新的随机密码, 长度: 12
35 | *
36 | * @return Random password
37 | * @since 1.1.0
38 | */
39 | public static String randomPassword() {
40 | return RandomStringUtils.random(12, true, true);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/infrastructure/README.txt:
--------------------------------------------------------------------------------
1 |
2 | All DAO, Data, Utils in Here
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/infrastructure/RandomUtils.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 |
4 | import org.apache.commons.lang3.RandomStringUtils;
5 |
6 | /**
7 | * 2016/12/25
8 | *
9 | * @author Shengzhao Li
10 | */
11 | public abstract class RandomUtils {
12 |
13 |
14 | public static String randomText() {
15 | return RandomStringUtils.random(32, true, true);
16 | }
17 |
18 |
19 | private RandomUtils() {
20 | }
21 |
22 | //全数字的随机值
23 | public static String randomNumber() {
24 | return RandomStringUtils.random(32, false, true);
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/infrastructure/jdbc/OauthClientDetailsRowMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
3 | * www.monkeyk.com
4 | * All rights reserved.
5 | *
6 | * This software is the confidential and proprietary information of
7 | * MONKEYK Information Technology Co. Ltd ("Confidential Information").
8 | * You shall not disclose such Confidential Information and shall use
9 | * it only in accordance with the terms of the license agreement you
10 | * entered into with MONKEYK Information Technology Co. Ltd.
11 | */
12 | package myoidc.server.infrastructure.jdbc;
13 |
14 |
15 | import myoidc.server.domain.oauth.OauthClientDetails;
16 | import org.springframework.jdbc.core.RowMapper;
17 |
18 | import java.sql.ResultSet;
19 | import java.sql.SQLException;
20 |
21 | /**
22 | * 2015/11/16
23 | *
24 | * from spring-oauth-server
25 | *
26 | * @author Shengzhao Li
27 | */
28 | public class OauthClientDetailsRowMapper implements RowMapper {
29 |
30 |
31 | public OauthClientDetailsRowMapper() {
32 | }
33 |
34 | @Override
35 | public OauthClientDetails mapRow(ResultSet rs, int i) throws SQLException {
36 | OauthClientDetails clientDetails = new OauthClientDetails();
37 |
38 | clientDetails.clientId(rs.getString("client_id"));
39 | clientDetails.resourceIds(rs.getString("resource_ids"));
40 | clientDetails.clientSecret(rs.getString("client_secret"));
41 |
42 | clientDetails.scope(rs.getString("scope"));
43 | clientDetails.authorizedGrantTypes(rs.getString("authorized_grant_types"));
44 | clientDetails.webServerRedirectUri(rs.getString("web_server_redirect_uri"));
45 |
46 | clientDetails.authorities(rs.getString("authorities"));
47 | clientDetails.accessTokenValidity(getInteger(rs, "access_token_validity"));
48 | clientDetails.refreshTokenValidity(getInteger(rs, "refresh_token_validity"));
49 |
50 | clientDetails.additionalInformation(rs.getString("additional_information"));
51 | clientDetails.createTime(rs.getTimestamp("create_time").toLocalDateTime());
52 | clientDetails.archived(rs.getBoolean("archived"));
53 |
54 | clientDetails.trusted(rs.getBoolean("trusted"));
55 | clientDetails.autoApprove(rs.getString("autoapprove"));
56 |
57 | return clientDetails;
58 | }
59 |
60 |
61 | private Integer getInteger(ResultSet rs, String columnName) throws SQLException {
62 | final Object object = rs.getObject(columnName);
63 | if (object != null) {
64 | return (Integer) object;
65 | }
66 | return null;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/infrastructure/jpa/UserRepositoryHibernate.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure.jpa;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import myoidc.server.domain.user.Privilege;
5 | import myoidc.server.domain.user.User;
6 | import myoidc.server.domain.user.UserRepository;
7 | import org.apache.commons.lang3.StringUtils;
8 | import org.springframework.stereotype.Repository;
9 |
10 | import javax.persistence.Query;
11 | import java.util.List;
12 |
13 | /**
14 | * 2018/3/22
15 | *
16 | * @author Shengzhao Li
17 | */
18 | @Repository()
19 | public class UserRepositoryHibernate extends AbstractRepositoryHibernate implements UserRepository {
20 |
21 |
22 | @Override
23 | public User findLoginUserByUsername(String username) {
24 | final String hql = "from User u where u.username = :username and u.archived = false";
25 | final List list = find(hql, ImmutableMap.of("username", username));
26 | return list.isEmpty() ? null : list.get(0);
27 | }
28 |
29 | @Override
30 | @SuppressWarnings("unchecked")
31 | public List findUserPrivileges(String userUuid) {
32 | final String hql = " select up.privilege from UserPrivilege up where up.archived = false and up.user.uuid = :userUuid";
33 | final Query query = session().createQuery(hql).setParameter("userUuid", userUuid);
34 | return query.getResultList();
35 | }
36 |
37 | @Override
38 | public List findUsersByUsername(String username) {
39 | if (StringUtils.isNoneBlank(username)) {
40 | final String hql = "from User u where u.username like :username and u.archived = false order by u.id desc ";
41 | // 右半 %, 使用索引
42 | return find(hql, ImmutableMap.of("username", username + "%"));
43 | } else {
44 | return find("from User u where u.archived = false order by u.id desc ");
45 | }
46 | }
47 |
48 | @Override
49 | public User findUserByUsernameNoArchived(String username) {
50 | final String hql = "from User u where u.username = :username ";
51 | final List list = find(hql, ImmutableMap.of("username", username));
52 | return list.isEmpty() ? null : list.get(0);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/infrastructure/oidc/MyOIDCAccessTokenConverter.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure.oidc;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.security.oauth2.common.OAuth2AccessToken;
6 | import org.springframework.security.oauth2.provider.OAuth2Authentication;
7 | import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
8 |
9 | import java.util.Map;
10 |
11 | /**
12 | * 2020/3/11
13 | *
14 | * Ext. default
15 | *
16 | * @author Shengzhao Li
17 | * @since 1.1.0
18 | */
19 | public class MyOIDCAccessTokenConverter extends DefaultAccessTokenConverter {
20 |
21 |
22 | private static final Logger LOG = LoggerFactory.getLogger(MyOIDCAccessTokenConverter.class);
23 |
24 |
25 | public MyOIDCAccessTokenConverter() {
26 | }
27 |
28 | @Override
29 | public Map convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
30 | return super.convertAccessToken(token, authentication);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/infrastructure/oidc/MyOIDCUserAuthenticationConverter.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure.oidc;
2 |
3 | import myoidc.server.domain.security.OIDCUserDetails;
4 | import myoidc.server.domain.shared.Application;
5 | import org.jose4j.jwt.ReservedClaimNames;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.security.core.Authentication;
9 | import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
10 |
11 | import java.util.HashMap;
12 | import java.util.Map;
13 |
14 | /**
15 | * 2020/3/11
16 | *
17 | * Ext. default
18 | *
19 | * @author Shengzhao Li
20 | * @since 1.1.0
21 | */
22 | public class MyOIDCUserAuthenticationConverter extends DefaultUserAuthenticationConverter {
23 |
24 | private static final Logger LOG = LoggerFactory.getLogger(MyOIDCUserAuthenticationConverter.class);
25 |
26 | public MyOIDCUserAuthenticationConverter() {
27 | }
28 |
29 | @Override
30 | public Map convertUserAuthentication(Authentication authentication) {
31 | Map myOIDCMap = new HashMap<>();
32 | Map oldMap = super.convertUserAuthentication(authentication);
33 | myOIDCMap.putAll(oldMap);
34 |
35 | //按协议规范增加 required 属性
36 | // https://openid.net/specs/openid-connect-core-1_0.html#IDToken
37 | myOIDCMap.put(ReservedClaimNames.ISSUER, Application.host());
38 | myOIDCMap.put(ReservedClaimNames.ISSUED_AT, System.currentTimeMillis() / 1000);
39 |
40 | Object details = authentication.getDetails();
41 | if (details instanceof OIDCUserDetails) {
42 | OIDCUserDetails userDetails = (OIDCUserDetails) details;
43 | myOIDCMap.put(ReservedClaimNames.SUBJECT, userDetails.user().uuid());
44 | } else {
45 | myOIDCMap.put(ReservedClaimNames.SUBJECT, myOIDCMap.get(USERNAME));
46 | }
47 | return myOIDCMap;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/infrastructure/oidc/OIDCUseScene.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure.oidc;
2 |
3 | /**
4 | * 2020/3/31
5 | *
6 | * OIDC具体的使用场景
7 | *
8 | * @author Shengzhao Li
9 | * @since 1.1.0
10 | */
11 | public enum OIDCUseScene {
12 |
13 | WEB(OIDCUtils.GrantType.AUTHORIZATION_CODE, OIDCUtils.GrantType.REFRESH_TOKEN), //浏览器
14 | CELL_PHONE(OIDCUtils.GrantType.PASSWORD, OIDCUtils.GrantType.REFRESH_TOKEN), //移动设备(手机)
15 | DEVICE_CLIENT(OIDCUtils.GrantType.PASSWORD, OIDCUtils.GrantType.REFRESH_TOKEN), // 其他设备
16 | SERVER(OIDCUtils.GrantType.CLIENT_CREDENTIALS); //服务端
17 |
18 |
19 | /**
20 | * 每种场景对应的 grant_types
21 | */
22 | private OIDCUtils.GrantType[] grantTypes;
23 |
24 | OIDCUseScene(OIDCUtils.GrantType... grantTypes) {
25 | this.grantTypes = grantTypes;
26 | }
27 |
28 |
29 | public OIDCUtils.GrantType[] grantTypes() {
30 | return this.grantTypes;
31 | }
32 |
33 | public boolean isServer() {
34 | return SERVER.equals(this);
35 | }
36 |
37 | public boolean isDeviceClient() {
38 | return DEVICE_CLIENT.equals(this);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/OauthService.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service;
2 |
3 |
4 | import myoidc.server.domain.oauth.OauthClientDetails;
5 | import myoidc.server.service.dto.OauthClientDetailsDto;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author Shengzhao Li
11 | */
12 |
13 | public interface OauthService {
14 |
15 | OauthClientDetails loadOauthClientDetails(String clientId);
16 |
17 | void archiveOauthClientDetails(String clientId);
18 |
19 | List loadOauthClientDetailsDtos(String clientId);
20 |
21 | String saveOAuthClientDetails(OauthClientDetailsDto formDto);
22 |
23 | OauthClientDetailsDto loadOauthClientDetailsDto(String clientId);
24 |
25 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/README.txt:
--------------------------------------------------------------------------------
1 |
2 | All Service,Business in Here
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/SecurityService.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service;
2 |
3 | import myoidc.server.service.dto.ClientRegistrationFormDto;
4 | import myoidc.server.service.dto.OauthClientDetailsDto;
5 | import myoidc.server.service.dto.UserJsonDto;
6 | import org.springframework.security.core.userdetails.UserDetailsService;
7 |
8 | /**
9 | * 2018/2/5
10 | *
11 | * @author Shengzhao Li
12 | */
13 | public interface SecurityService extends UserDetailsService {
14 |
15 | UserJsonDto loadCurrentUserJsonDto();
16 |
17 | OauthClientDetailsDto saveClientRegistrationForm(ClientRegistrationFormDto formDto);
18 | }
19 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/UserService.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service;
2 |
3 | import myoidc.server.service.dto.UserFormDto;
4 | import myoidc.server.service.dto.UserListDto;
5 |
6 | /**
7 | * 2020/3/18
8 | *
9 | * @author Shengzhao Li
10 | * @since 1.1.0
11 | */
12 | public interface UserService {
13 |
14 |
15 | UserListDto loadUserListDto(UserListDto listDto);
16 |
17 | boolean isExistedUsername(String username);
18 |
19 | String saveUserForm(UserFormDto formDto);
20 |
21 | boolean archiveUserByUuid(String uuid);
22 | }
23 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/business/ClientRegistrationFormSaver.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.business;
2 |
3 | import myoidc.server.Constants;
4 | import myoidc.server.domain.oauth.OauthClientDetails;
5 | import myoidc.server.domain.oauth.OauthRepository;
6 | import myoidc.server.domain.shared.BeanProvider;
7 | import myoidc.server.domain.user.Privilege;
8 | import myoidc.server.infrastructure.PasswordHandler;
9 | import myoidc.server.infrastructure.oidc.OIDCUseScene;
10 | import myoidc.server.infrastructure.oidc.OIDCUtils;
11 | import myoidc.server.service.dto.ClientRegistrationFormDto;
12 | import myoidc.server.service.dto.OauthClientDetailsDto;
13 | import myoidc.server.web.WebUtils;
14 | import org.apache.commons.lang3.StringUtils;
15 | import org.jose4j.jwt.JwtClaims;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | /**
20 | * 2020/4/1
21 | *
22 | * @author Shengzhao Li
23 | * @since 1.1.0
24 | */
25 | public class ClientRegistrationFormSaver {
26 |
27 |
28 | private static final Logger LOG = LoggerFactory.getLogger(ClientRegistrationFormSaver.class);
29 |
30 | private OauthRepository oauthRepository = BeanProvider.getBean(OauthRepository.class);
31 |
32 |
33 | private ClientRegistrationFormDto formDto;
34 |
35 | public ClientRegistrationFormSaver(ClientRegistrationFormDto formDto) {
36 | this.formDto = formDto;
37 | }
38 |
39 |
40 | public OauthClientDetailsDto save() {
41 |
42 | OauthClientDetails clientDetails = createDomain();
43 | String clientSecret = OIDCUtils.generateClientSecret();
44 | // encrypted client secret
45 | clientDetails.clientSecret(PasswordHandler.encode(clientSecret));
46 |
47 | oauthRepository.saveOauthClientDetails(clientDetails);
48 | LOG.debug("{}|Register OauthClientDetails: {}", WebUtils.getIp(), clientDetails);
49 |
50 | OauthClientDetails oauthClientDetails = oauthRepository.findOauthClientDetails(clientDetails.clientId());
51 | OauthClientDetailsDto detailsDto = new OauthClientDetailsDto(oauthClientDetails);
52 | detailsDto.setClientSecret(clientSecret);
53 | return detailsDto;
54 | }
55 |
56 |
57 | OauthClientDetails createDomain() {
58 | OIDCUseScene useScene = formDto.getUseScene();
59 | OauthClientDetails clientDetails = new OauthClientDetails()
60 | .clientId(OIDCUtils.generateClientId())
61 | .resourceIds(Constants.RESOURCE_ID)
62 | .authorizedGrantTypes(StringUtils.join(useScene.grantTypes(), ","));
63 |
64 |
65 | //判断scope
66 | if (useScene.isServer()) {
67 | clientDetails.scope(OIDCUtils.SCOPE_READ);
68 | } else {
69 | clientDetails.scope(OIDCUtils.SCOPE_OPENID);
70 | }
71 | clientDetails.webServerRedirectUri(formDto.getWebServerRedirectUri());
72 |
73 | //权限默认 CLIENT
74 | clientDetails.authorities(Privilege.CLIENT.name());
75 |
76 | //固定值
77 | clientDetails.accessTokenValidity(OIDCUtils.ACCESS_TOKEN_VALIDITY)
78 | .refreshTokenValidity(OIDCUtils.REFRESH_TOKEN_VALIDITY)
79 | .trusted(false);
80 |
81 | JwtClaims claims = new JwtClaims();
82 | claims.setStringClaim("appName", formDto.getAppName());
83 | clientDetails.additionalInformation(claims.toJson());
84 |
85 | return clientDetails;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/business/OAuthClientDetailsSaver.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.business;
2 |
3 | import myoidc.server.domain.oauth.OauthClientDetails;
4 | import myoidc.server.domain.oauth.OauthRepository;
5 | import myoidc.server.domain.shared.BeanProvider;
6 | import myoidc.server.service.dto.OauthClientDetailsDto;
7 | import myoidc.server.web.WebUtils;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | /**
12 | * 2020/3/21
13 | *
14 | * @author Shengzhao Li
15 | * @since 1.1.0
16 | */
17 | public class OAuthClientDetailsSaver {
18 |
19 |
20 | private static final Logger LOG = LoggerFactory.getLogger(OAuthClientDetailsSaver.class);
21 |
22 | private OauthRepository oauthRepository = BeanProvider.getBean(OauthRepository.class);
23 |
24 | private OauthClientDetailsDto formDto;
25 |
26 | public OAuthClientDetailsSaver(OauthClientDetailsDto formDto) {
27 | this.formDto = formDto;
28 | }
29 |
30 | public String save() {
31 | OauthClientDetails clientDetails = formDto.createDomain();
32 | oauthRepository.saveOauthClientDetails(clientDetails);
33 | LOG.debug("{}|Save OauthClientDetails: {}", WebUtils.getIp(), clientDetails);
34 | return clientDetails.clientId();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/business/UserFormSaver.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.business;
2 |
3 | import myoidc.server.domain.security.SecurityUtils;
4 | import myoidc.server.domain.shared.BeanProvider;
5 | import myoidc.server.domain.user.Privilege;
6 | import myoidc.server.domain.user.User;
7 | import myoidc.server.domain.user.UserPrivilege;
8 | import myoidc.server.domain.user.UserRepository;
9 | import myoidc.server.service.dto.UserFormDto;
10 | import myoidc.server.web.WebUtils;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * 2020/3/19
18 | *
19 | * @author Shengzhao Li
20 | * @since 1.1.0
21 | */
22 | public class UserFormSaver {
23 |
24 | private static final Logger LOG = LoggerFactory.getLogger(UserFormSaver.class);
25 |
26 |
27 | private UserRepository userRepository = BeanProvider.getBean(UserRepository.class);
28 |
29 | // private PasswordEncoder passwordEncoder = BeanProvider.getBean(PasswordEncoder.class);
30 |
31 |
32 | private UserFormDto formDto;
33 |
34 | public UserFormSaver(UserFormDto formDto) {
35 | this.formDto = formDto;
36 | }
37 |
38 | public String save() {
39 |
40 | User user = formDto.newUser();
41 | user.creator(SecurityUtils.currentUser());
42 | // user.password(passwordEncoder.encode(formDto.getPassword()));
43 | userRepository.saveOrUpdate(user);
44 |
45 | List privileges = formDto.getPrivileges();
46 | for (Privilege privilege : privileges) {
47 | UserPrivilege userPrivilege = new UserPrivilege(user, privilege);
48 | userRepository.saveOrUpdate(userPrivilege);
49 | }
50 |
51 | LOG.debug("{}|Save User: {}", WebUtils.getIp(), user);
52 | return user.uuid();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/dto/ClientRegistrationFormDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.dto;
2 |
3 | import myoidc.server.infrastructure.oidc.OIDCUseScene;
4 | import org.hibernate.validator.constraints.URL;
5 |
6 | import javax.validation.constraints.NotBlank;
7 | import javax.validation.constraints.NotNull;
8 | import javax.validation.constraints.Size;
9 | import java.io.Serializable;
10 |
11 | /**
12 | * 2020/4/1
13 | *
14 | *
15 | * 客户端 注册 DTO
16 | *
17 | * @author Shengzhao Li
18 | * @since 1.1.0
19 | */
20 | public class ClientRegistrationFormDto implements Serializable {
21 | private static final long serialVersionUID = -6634612576542523523L;
22 |
23 |
24 | //应用名称
25 | @NotBlank(message = "应用名称不能为空")
26 | @Size(min = 1, max = 20, message = "应用名称最多20字符")
27 | private String appName;
28 |
29 |
30 | @NotBlank(message = "redirect_uri不能为空")
31 | @URL(message = "redirect_uri格式错误")
32 | private String webServerRedirectUri;
33 |
34 |
35 | //场景
36 | @NotNull(message = "useScene is required")
37 | private OIDCUseScene useScene;
38 |
39 |
40 | public ClientRegistrationFormDto() {
41 | }
42 |
43 | public ClientRegistrationFormDto(OIDCUseScene useScene) {
44 | this.useScene = useScene;
45 | }
46 |
47 |
48 | public String getAppName() {
49 | return appName;
50 | }
51 |
52 | public void setAppName(String appName) {
53 | this.appName = appName;
54 | }
55 |
56 | public String getWebServerRedirectUri() {
57 | return webServerRedirectUri;
58 | }
59 |
60 | public void setWebServerRedirectUri(String webServerRedirectUri) {
61 | this.webServerRedirectUri = webServerRedirectUri;
62 | }
63 |
64 | public OIDCUseScene getUseScene() {
65 | return useScene;
66 | }
67 |
68 | public void setUseScene(OIDCUseScene useScene) {
69 | this.useScene = useScene;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/dto/OAuthResourceDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.dto;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 2018/3/26
7 | *
8 | * @author Shengzhao Li
9 | */
10 | public class OAuthResourceDto implements Serializable {
11 | private static final long serialVersionUID = -7266690020307910479L;
12 |
13 |
14 | private String resourceId;
15 |
16 | private String description;
17 |
18 |
19 | public OAuthResourceDto() {
20 | }
21 |
22 | public OAuthResourceDto(String resourceId, String description) {
23 | this.resourceId = resourceId;
24 | this.description = description;
25 | }
26 |
27 |
28 | public String getResourceId() {
29 | return resourceId;
30 | }
31 |
32 | public void setResourceId(String resourceId) {
33 | this.resourceId = resourceId;
34 | }
35 |
36 | public String getDescription() {
37 | return description;
38 | }
39 |
40 | public void setDescription(String description) {
41 | this.description = description;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/dto/UserFormDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.dto;
2 |
3 |
4 | import myoidc.server.domain.user.Privilege;
5 | import myoidc.server.domain.user.User;
6 | import myoidc.server.infrastructure.PasswordHandler;
7 | import myoidc.server.service.validation.UsernameValidation;
8 | import org.hibernate.validator.constraints.Length;
9 |
10 | import javax.validation.constraints.Email;
11 | import javax.validation.constraints.NotBlank;
12 | import javax.validation.constraints.Size;
13 | import java.io.Serializable;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | /**
18 | * 2016/3/25
19 | *
20 | * From spring-oauth-server
21 | *
22 | * @author Shengzhao Li
23 | * @since 1.1.0
24 | */
25 | public class UserFormDto implements Serializable {
26 | private static final long serialVersionUID = 7959857016962260738L;
27 |
28 | private String uuid;
29 |
30 |
31 | @UsernameValidation()
32 | private String username;
33 |
34 |
35 | private String phone;
36 |
37 | @Email(message = "邮箱格式不对")
38 | private String email;
39 |
40 | //密码要求至少 10位
41 | @NotBlank(message = "密码不能为空")
42 | @Length(min = 10, message = "密码长度最少10位")
43 | private String password;
44 |
45 |
46 | @Size(min = 1, message = "至少选择一个权限")
47 | private List privileges = new ArrayList<>();
48 |
49 |
50 | public UserFormDto() {
51 | }
52 |
53 |
54 | public Privilege[] getAllPrivileges() {
55 | return Privilege.values();
56 | }
57 |
58 | public String getPassword() {
59 | return password;
60 | }
61 |
62 | public void setPassword(String password) {
63 | this.password = password;
64 | }
65 |
66 | public User newUser() {
67 | final User user = new User()
68 | .username(getUsername())
69 | .phone(getPhone())
70 | .email(getEmail())
71 | .password(PasswordHandler.encode(getPassword()));
72 | user.privileges().addAll(getPrivileges());
73 | return user;
74 | }
75 |
76 |
77 | public String getUuid() {
78 | return uuid;
79 | }
80 |
81 | public void setUuid(String uuid) {
82 | this.uuid = uuid;
83 | }
84 |
85 | public String getUsername() {
86 | return username;
87 | }
88 |
89 | public void setUsername(String username) {
90 | this.username = username;
91 | }
92 |
93 | public String getPhone() {
94 | return phone;
95 | }
96 |
97 | public void setPhone(String phone) {
98 | this.phone = phone;
99 | }
100 |
101 | public String getEmail() {
102 | return email;
103 | }
104 |
105 | public void setEmail(String email) {
106 | this.email = email;
107 | }
108 |
109 | public List getPrivileges() {
110 | return privileges;
111 | }
112 |
113 | public void setPrivileges(List privileges) {
114 | this.privileges = privileges;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/dto/UserJsonDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.dto;
2 |
3 |
4 | import myoidc.server.domain.user.Privilege;
5 | import myoidc.server.domain.user.User;
6 |
7 | import java.io.Serializable;
8 | import java.time.temporal.ChronoField;
9 | import java.time.temporal.TemporalField;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | /**
14 | * @author Shengzhao Li
15 | */
16 | public class UserJsonDto implements Serializable {
17 |
18 |
19 | private static final long serialVersionUID = 2310668385840569887L;
20 |
21 | private String openid;
22 | // private boolean archived;
23 |
24 | private String username;
25 | private String phone;
26 | private String email;
27 |
28 | private long create_time;
29 |
30 | private List privileges = new ArrayList<>();
31 |
32 | public UserJsonDto() {
33 | }
34 |
35 | public UserJsonDto(User user) {
36 | this.openid = user.uuid();
37 | // this.archived = user.archived();
38 | this.username = user.username();
39 | this.create_time = user.createTime().getLong(ChronoField.MILLI_OF_SECOND);
40 |
41 | this.phone = user.phone();
42 | this.email = user.email();
43 |
44 | final List privilegeList = user.privileges();
45 | for (Privilege privilege : privilegeList) {
46 | this.privileges.add(privilege.name());
47 | }
48 | }
49 |
50 |
51 | public long getCreate_time() {
52 | return create_time;
53 | }
54 |
55 | public void setCreate_time(long create_time) {
56 | this.create_time = create_time;
57 | }
58 |
59 | public String getOpenid() {
60 | return openid;
61 | }
62 |
63 | public void setOpenid(String openid) {
64 | this.openid = openid;
65 | }
66 |
67 | // public boolean isArchived() {
68 | // return archived;
69 | // }
70 |
71 | // public void setArchived(boolean archived) {
72 | // this.archived = archived;
73 | // }
74 |
75 |
76 | public String getUsername() {
77 | return username;
78 | }
79 |
80 | public void setUsername(String username) {
81 | this.username = username;
82 | }
83 |
84 | public String getPhone() {
85 | return phone;
86 | }
87 |
88 | public void setPhone(String phone) {
89 | this.phone = phone;
90 | }
91 |
92 | public String getEmail() {
93 | return email;
94 | }
95 |
96 | public void setEmail(String email) {
97 | this.email = email;
98 | }
99 |
100 | public List getPrivileges() {
101 | return privileges;
102 | }
103 |
104 | public void setPrivileges(List privileges) {
105 | this.privileges = privileges;
106 | }
107 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/dto/UserListDto.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.dto;
2 |
3 | import java.io.Serializable;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | /**
8 | * 2016/3/12
9 | *
10 | * @author Shengzhao Li
11 | */
12 | public class UserListDto implements Serializable {
13 | private static final long serialVersionUID = 2023379587030489248L;
14 |
15 |
16 | private String username;
17 |
18 |
19 | private List userDtos = new ArrayList<>();
20 |
21 |
22 | public UserListDto() {
23 | }
24 |
25 | public int getSize() {
26 | return userDtos.size();
27 | }
28 |
29 | public String getUsername() {
30 | return username;
31 | }
32 |
33 | public void setUsername(String username) {
34 | this.username = username;
35 | }
36 |
37 | public List getUserDtos() {
38 | return userDtos;
39 | }
40 |
41 | public void setUserDtos(List userDtos) {
42 | this.userDtos = userDtos;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/impl/OauthServiceImpl.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.impl;
2 |
3 | import myoidc.server.domain.oauth.OauthClientDetails;
4 | import myoidc.server.domain.oauth.OauthRepository;
5 | import myoidc.server.service.OauthService;
6 | import myoidc.server.service.business.OAuthClientDetailsSaver;
7 | import myoidc.server.service.dto.OauthClientDetailsDto;
8 | import myoidc.server.web.WebUtils;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Service;
13 | import org.springframework.transaction.annotation.Transactional;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * 2018/3/24
19 | *
20 | * from spring-oauth-server
21 | *
22 | * @author Shengzhao Li
23 | */
24 | @Service("oauthService")
25 | public class OauthServiceImpl implements OauthService {
26 |
27 | private static final Logger LOG = LoggerFactory.getLogger(OauthServiceImpl.class);
28 |
29 |
30 | @Autowired
31 | private OauthRepository oauthRepository;
32 |
33 |
34 | @Transactional(readOnly = true)
35 | @Override
36 | public OauthClientDetails loadOauthClientDetails(String clientId) {
37 | return oauthRepository.findOauthClientDetails(clientId);
38 | }
39 |
40 |
41 | @Transactional()
42 | @Override
43 | public void archiveOauthClientDetails(String clientId) {
44 | int i = oauthRepository.updateOauthClientDetailsArchive(clientId, true);
45 | LOG.debug("{}|Archived client: {}, {}", WebUtils.getIp(), clientId, i);
46 | }
47 |
48 | @Transactional(readOnly = true)
49 | @Override
50 | public List loadOauthClientDetailsDtos(String clientId) {
51 | //暂时不加分页
52 | List clientDetailses = oauthRepository.findAllOauthClientDetails(clientId);
53 | return OauthClientDetailsDto.toDtos(clientDetailses);
54 | }
55 |
56 | @Transactional()
57 | @Override
58 | public String saveOAuthClientDetails(OauthClientDetailsDto formDto) {
59 | OAuthClientDetailsSaver saver = new OAuthClientDetailsSaver(formDto);
60 | return saver.save();
61 | }
62 |
63 | @Transactional(readOnly = true)
64 | @Override
65 | public OauthClientDetailsDto loadOauthClientDetailsDto(String clientId) {
66 | final OauthClientDetails oauthClientDetails = oauthRepository.findOauthClientDetails(clientId);
67 | return oauthClientDetails != null ? new OauthClientDetailsDto(oauthClientDetails) : null;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/impl/SecurityServiceImpl.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.impl;
2 |
3 | import myoidc.server.domain.security.OIDCUserDetails;
4 | import myoidc.server.domain.user.User;
5 | import myoidc.server.domain.user.UserRepository;
6 | import myoidc.server.service.SecurityService;
7 | import myoidc.server.service.business.ClientRegistrationFormSaver;
8 | import myoidc.server.service.dto.ClientRegistrationFormDto;
9 | import myoidc.server.service.dto.OauthClientDetailsDto;
10 | import myoidc.server.service.dto.UserJsonDto;
11 | import myoidc.server.service.oauth.CurrentUserJsonDtoLoader;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 | import org.springframework.beans.factory.annotation.Autowired;
15 | import org.springframework.security.core.userdetails.UserDetails;
16 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
17 | import org.springframework.stereotype.Service;
18 | import org.springframework.transaction.annotation.Transactional;
19 |
20 | /**
21 | * 2018/2/5
22 | *
23 | * @author Shengzhao Li
24 | */
25 | @Service()
26 | public class SecurityServiceImpl implements SecurityService {
27 |
28 | private static final Logger LOG = LoggerFactory.getLogger(SecurityServiceImpl.class);
29 |
30 | @Autowired
31 | private UserRepository userRepository;
32 |
33 |
34 | @Transactional(readOnly = true)
35 | @Override
36 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
37 | LOG.debug("Try load User by username: {}", username);
38 | User user = userRepository.findLoginUserByUsername(username);
39 | if (user == null) {
40 | throw new UsernameNotFoundException("Not found by username: " + username);
41 | }
42 | return new OIDCUserDetails(user);
43 | }
44 |
45 |
46 | /**
47 | * 获取当前登录用户 的信息 , JSON
48 | */
49 | @Override
50 | @Transactional(readOnly = true)
51 | public UserJsonDto loadCurrentUserJsonDto() {
52 | CurrentUserJsonDtoLoader loader = new CurrentUserJsonDtoLoader();
53 | return loader.load();
54 | }
55 |
56 | @Override
57 | @Transactional()
58 | public OauthClientDetailsDto saveClientRegistrationForm(ClientRegistrationFormDto formDto) {
59 | ClientRegistrationFormSaver formSaver = new ClientRegistrationFormSaver(formDto);
60 | return formSaver.save();
61 | }
62 |
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/impl/UserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.impl;
2 |
3 | import myoidc.server.domain.user.User;
4 | import myoidc.server.domain.user.UserRepository;
5 | import myoidc.server.service.UserService;
6 | import myoidc.server.service.business.UserFormSaver;
7 | import myoidc.server.service.dto.UserDto;
8 | import myoidc.server.service.dto.UserFormDto;
9 | import myoidc.server.service.dto.UserListDto;
10 | import myoidc.server.web.WebUtils;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.stereotype.Service;
15 | import org.springframework.transaction.annotation.Transactional;
16 |
17 | import java.util.List;
18 |
19 | /**
20 | * 2020/3/18
21 | *
22 | * @author Shengzhao Li
23 | * @since 1.1.0
24 | */
25 | @Service
26 | public class UserServiceImpl implements UserService {
27 |
28 | private static final Logger LOG = LoggerFactory.getLogger(UserServiceImpl.class);
29 |
30 |
31 | @Autowired
32 | private UserRepository userRepository;
33 |
34 |
35 | @Override
36 | @Transactional(readOnly = true)
37 | public UserListDto loadUserListDto(UserListDto listDto) {
38 | //暂不支持分页
39 | List users = userRepository.findUsersByUsername(listDto.getUsername());
40 | listDto.setUserDtos(UserDto.toDtos(users));
41 | return listDto;
42 | }
43 |
44 | @Override
45 | @Transactional(readOnly = true)
46 | public boolean isExistedUsername(String username) {
47 | final User user = userRepository.findUserByUsernameNoArchived(username);
48 | return user != null;
49 | }
50 |
51 | @Override
52 | @Transactional()
53 | public String saveUserForm(UserFormDto formDto) {
54 | UserFormSaver saver = new UserFormSaver(formDto);
55 | return saver.save();
56 | }
57 |
58 | @Override
59 | @Transactional()
60 | public boolean archiveUserByUuid(String uuid) {
61 | User user = userRepository.findByUuid(User.class, uuid);
62 | if (user == null || user.defaultUser()) {
63 | LOG.debug("{}|Null or defaultUser: {}", WebUtils.getIp(), user);
64 | return false;
65 | }
66 | user.archiveMe();
67 | return true;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/oauth/CurrentUserJsonDtoLoader.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.oauth;
2 |
3 | import myoidc.server.domain.security.OIDCUserDetails;
4 | import myoidc.server.domain.shared.BeanProvider;
5 | import myoidc.server.domain.user.User;
6 | import myoidc.server.domain.user.UserRepository;
7 | import myoidc.server.service.dto.UserJsonDto;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.security.core.Authentication;
11 | import org.springframework.security.core.GrantedAuthority;
12 | import org.springframework.security.core.context.SecurityContextHolder;
13 | import org.springframework.security.oauth2.provider.OAuth2Authentication;
14 |
15 | import java.util.Collection;
16 |
17 | /**
18 | * 2020/3/11
19 | *
20 | * @author Shengzhao Li
21 | * @since 1.1.0
22 | */
23 | public class CurrentUserJsonDtoLoader {
24 |
25 | private static final Logger LOG = LoggerFactory.getLogger(CurrentUserJsonDtoLoader.class);
26 |
27 |
28 | private transient UserRepository userRepository = BeanProvider.getBean(UserRepository.class);
29 |
30 | public CurrentUserJsonDtoLoader() {
31 | }
32 |
33 | public UserJsonDto load() {
34 | final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
35 | final Object principal = authentication.getPrincipal();
36 |
37 | if (authentication instanceof OAuth2Authentication &&
38 | (principal instanceof String || principal instanceof org.springframework.security.core.userdetails.User)) {
39 | return loadOauthUserJsonDto((OAuth2Authentication) authentication);
40 | } else {
41 | final OIDCUserDetails userDetails = (OIDCUserDetails) principal;
42 | return new UserJsonDto(userRepository.findByUuid(User.class, userDetails.user().uuid()));
43 | }
44 | }
45 |
46 |
47 | private UserJsonDto loadOauthUserJsonDto(OAuth2Authentication oAuth2Authentication) {
48 | String name = oAuth2Authentication.getName();
49 | User user = userRepository.findLoginUserByUsername(name);
50 | UserJsonDto userJsonDto;
51 | if (user != null) {
52 | LOG.debug("Load OAuth user from User: {}", user);
53 | userJsonDto = new UserJsonDto(user);
54 | } else {
55 | userJsonDto = new UserJsonDto();
56 | userJsonDto.setUsername(name);
57 |
58 | final Collection authorities = oAuth2Authentication.getAuthorities();
59 | for (GrantedAuthority authority : authorities) {
60 | userJsonDto.getPrivileges().add(authority.getAuthority());
61 | }
62 | }
63 | return userJsonDto;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/oauth/CustomJdbcClientDetailsService.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.oauth;
2 |
3 | import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
4 | import org.springframework.security.oauth2.provider.ClientDetails;
5 | import org.springframework.security.oauth2.provider.NoSuchClientException;
6 | import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
7 |
8 | import javax.sql.DataSource;
9 |
10 |
11 | /**
12 | * 扩展 默认的 ClientDetailsService, 增加逻辑删除判断( archived = 0)
13 | * SQL中添加 archived = 0 条件
14 | *
15 | * from spring-oauth-server
16 | *
17 | * @author Shengzhao Li
18 | */
19 | public class CustomJdbcClientDetailsService extends JdbcClientDetailsService {
20 |
21 | private static final String SELECT_CLIENT_DETAILS_SQL = "select client_id, client_secret, resource_ids, scope, authorized_grant_types, " +
22 | "web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove " +
23 | "from oauth_client_details where client_id = ? and archived = 0 ";
24 |
25 |
26 | public CustomJdbcClientDetailsService(DataSource dataSource) {
27 | super(dataSource);
28 | setSelectClientDetailsSql(SELECT_CLIENT_DETAILS_SQL);
29 | }
30 |
31 |
32 | @Override
33 | // @Cacheable(value = CLIENT_DETAILS_CACHE, key = "#clientId")
34 | public ClientDetails loadClientByClientId(String clientId) throws InvalidClientException {
35 | return super.loadClientByClientId(clientId);
36 | }
37 |
38 |
39 | @Override
40 | // @CacheEvict(value = CLIENT_DETAILS_CACHE, key = "#clientDetails.getClientId()")
41 | public void updateClientDetails(ClientDetails clientDetails) throws NoSuchClientException {
42 | super.updateClientDetails(clientDetails);
43 | }
44 |
45 | @Override
46 | // @CacheEvict(value = CLIENT_DETAILS_CACHE, key = "#clientId")
47 | public void updateClientSecret(String clientId, String secret) throws NoSuchClientException {
48 | super.updateClientSecret(clientId, secret);
49 | }
50 |
51 | @Override
52 | // @CacheEvict(value = CLIENT_DETAILS_CACHE, key = "#clientId")
53 | public void removeClientDetails(String clientId) throws NoSuchClientException {
54 | super.removeClientDetails(clientId);
55 | }
56 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/oauth/CustomJdbcTokenStore.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.oauth;
2 |
3 | import org.springframework.security.oauth2.common.OAuth2AccessToken;
4 | import org.springframework.security.oauth2.common.OAuth2RefreshToken;
5 | import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
6 |
7 | import javax.sql.DataSource;
8 |
9 |
10 |
11 | /**
12 | * 2016/7/26
13 | *
14 | * 扩展默认的 TokenStore, 增加对缓存的支持
15 | *
16 | *
17 | * from spring-oauth-server
18 | *
19 | * @author Shengzhao Li
20 | */
21 | public class CustomJdbcTokenStore extends JdbcTokenStore {
22 |
23 |
24 | public CustomJdbcTokenStore(DataSource dataSource) {
25 | super(dataSource);
26 | }
27 |
28 |
29 | // @Cacheable(value = ACCESS_TOKEN_CACHE, key = "#tokenValue")
30 | public OAuth2AccessToken readAccessToken(String tokenValue) {
31 | return super.readAccessToken(tokenValue);
32 | }
33 |
34 | // @CacheEvict(value = ACCESS_TOKEN_CACHE, key = "#token.value")
35 | @Override
36 | public void removeAccessToken(OAuth2AccessToken token) {
37 | super.removeAccessToken(token);
38 | }
39 |
40 | // @Cacheable(value = REFRESH_TOKEN_CACHE, key = "#token")
41 | public OAuth2RefreshToken readRefreshToken(String token) {
42 | return super.readRefreshToken(token);
43 | }
44 |
45 | // @CacheEvict(value = REFRESH_TOKEN_CACHE, key = "#token.value")
46 | @Override
47 | public void removeRefreshToken(OAuth2RefreshToken token) {
48 | super.removeRefreshToken(token);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/oauth/OauthUserApprovalHandler.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.oauth;
2 |
3 |
4 | import myoidc.server.domain.oauth.OauthClientDetails;
5 | import myoidc.server.service.OauthService;
6 | import org.springframework.security.core.Authentication;
7 | import org.springframework.security.oauth2.provider.AuthorizationRequest;
8 | import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
9 |
10 | /**
11 | * 处理OAuth 中用户授权确认的逻辑
12 | * 这在grant_type 为 authorization_code, implicit 会使用到
13 | *
14 | * from spring-oauth-server
15 | *
16 | * @author Shengzhao Li
17 | */
18 | public class OauthUserApprovalHandler extends TokenStoreUserApprovalHandler {
19 |
20 | private OauthService oauthService;
21 |
22 | public OauthUserApprovalHandler() {
23 | // Do nothing
24 | }
25 |
26 |
27 | /**
28 | * 这儿扩展了默认的逻辑, 若 OauthClientDetails 中的 trusted 字段为true, 将会自动跳过 授权流程
29 | *
30 | * @param authorizationRequest AuthorizationRequest
31 | * @param userAuthentication Authentication
32 | * @return True is approved
33 | */
34 | public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) {
35 | if (super.isApproved(authorizationRequest, userAuthentication)) {
36 | return true;
37 | }
38 | if (!userAuthentication.isAuthenticated()) {
39 | return false;
40 | }
41 |
42 | OauthClientDetails clientDetails = oauthService.loadOauthClientDetails(authorizationRequest.getClientId());
43 | return clientDetails != null && clientDetails.trusted();
44 |
45 | }
46 |
47 | public void setOauthService(OauthService oauthService) {
48 | this.oauthService = oauthService;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/oauth/SOSAuthorizationCodeServices.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.oauth;
2 |
3 | import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
4 | import org.springframework.security.oauth2.provider.OAuth2Authentication;
5 | import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
6 |
7 | import javax.sql.DataSource;
8 |
9 |
10 | /**
11 | * 2016/7/23
12 | *
13 | * from spring-oauth-server
14 | *
15 | * @author Shengzhao Li
16 | */
17 | public class SOSAuthorizationCodeServices extends JdbcAuthorizationCodeServices {
18 |
19 |
20 | // 扩展长度 18
21 | private RandomValueStringGenerator generator = new RandomValueStringGenerator(18);
22 |
23 |
24 | public SOSAuthorizationCodeServices(DataSource dataSource) {
25 | super(dataSource);
26 | }
27 |
28 |
29 | public String createAuthorizationCode(OAuth2Authentication authentication) {
30 | String code = generator.generate();
31 | store(code, authentication);
32 | return code;
33 | }
34 |
35 | @Override
36 | // @Cacheable(value = AUTHORIZATION_CODE_CACHE, key = "#code")
37 | protected void store(String code, OAuth2Authentication authentication) {
38 | super.store(code, authentication);
39 | }
40 |
41 | @Override
42 | // @CacheEvict(value = AUTHORIZATION_CODE_CACHE, key = "#code")
43 | public OAuth2Authentication remove(String code) {
44 | return super.remove(code);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/validation/ClientIdValidation.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.validation;
2 |
3 | import javax.validation.Constraint;
4 | import javax.validation.Payload;
5 | import java.lang.annotation.*;
6 |
7 | /**
8 | * 2020/3/21
9 | *
10 | * @author Shengzhao Li
11 | * @since 1.1.0
12 | */
13 | @Documented
14 | @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE})
15 | @Retention(RetentionPolicy.RUNTIME)
16 | @Constraint(validatedBy = ClientIdValidator.class)
17 | public @interface ClientIdValidation {
18 |
19 | String message() default "client_id不能为空(或已存在)";
20 |
21 | Class>[] groups() default {};
22 |
23 | Class extends Payload>[] payload() default {};
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/validation/ClientIdValidator.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.validation;
2 |
3 | import myoidc.server.service.OauthService;
4 | import myoidc.server.service.dto.OauthClientDetailsDto;
5 | import org.apache.commons.lang3.StringUtils;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 |
10 | import javax.validation.ConstraintValidator;
11 | import javax.validation.ConstraintValidatorContext;
12 |
13 | /**
14 | * 2020/3/21
15 | *
16 | * @author Shengzhao Li
17 | * @since 1.1.0
18 | */
19 | public class ClientIdValidator implements ConstraintValidator {
20 |
21 |
22 | private static final Logger LOG = LoggerFactory.getLogger(ClientIdValidator.class);
23 |
24 | @Autowired
25 | private OauthService oauthService;
26 |
27 | @Override
28 | public boolean isValid(String clientId, ConstraintValidatorContext context) {
29 | if (StringUtils.isBlank(clientId)) {
30 | LOG.debug("ClientId is blank");
31 | return false;
32 | }
33 |
34 |
35 | OauthClientDetailsDto detailsDto = oauthService.loadOauthClientDetailsDto(clientId);
36 | if (detailsDto != null) {
37 | LOG.warn("ClientId: {} existed", clientId);
38 | return false;
39 | }
40 |
41 | return true;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/validation/UsernameValidation.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.validation;
2 |
3 | import javax.validation.Constraint;
4 | import javax.validation.Payload;
5 | import java.lang.annotation.*;
6 |
7 | /**
8 | * 2020/3/18
9 | *
10 | * @author Shengzhao Li
11 | * @since 1.1.0
12 | */
13 | @Documented
14 | @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE})
15 | @Retention(RetentionPolicy.RUNTIME)
16 | @Constraint(validatedBy = UsernameValidator.class)
17 | public @interface UsernameValidation {
18 |
19 | String message() default "账号已经存在";
20 |
21 | Class>[] groups() default {};
22 |
23 | Class extends Payload>[] payload() default {};
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/service/validation/UsernameValidator.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.validation;
2 |
3 | import myoidc.server.service.UserService;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 |
9 | import javax.validation.ConstraintValidator;
10 | import javax.validation.ConstraintValidatorContext;
11 |
12 | /**
13 | * 2020/3/18
14 | *
15 | * @author Shengzhao Li
16 | * @since 1.1.0
17 | */
18 | public class UsernameValidator implements ConstraintValidator {
19 |
20 |
21 | private static final Logger LOG = LoggerFactory.getLogger(UsernameValidator.class);
22 |
23 | @Autowired
24 | private UserService userService;
25 |
26 | @Override
27 | public boolean isValid(String username, ConstraintValidatorContext constraintValidatorContext) {
28 | if (StringUtils.isBlank(username)) {
29 | LOG.debug("Username is blank");
30 | return false;
31 | }
32 |
33 | boolean existed = userService.isExistedUsername(username);
34 | if (existed) {
35 | LOG.debug("Username: {} existed", username);
36 | return false;
37 | }
38 |
39 | return true;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/README.txt:
--------------------------------------------------------------------------------
1 |
2 | All WEB in Here
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/WebUtils.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web;
2 |
3 |
4 | import org.apache.commons.lang3.StringUtils;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 |
8 | /**
9 | * Web 操作的 封装 工具类
10 | *
11 | * @author Shengzhao Li
12 | */
13 | public abstract class WebUtils {
14 |
15 |
16 | private static ThreadLocal ipThreadLocal = new ThreadLocal<>();
17 |
18 |
19 | private WebUtils() {
20 | }
21 |
22 | public static void setIp(String ip) {
23 | ipThreadLocal.set(ip);
24 | }
25 |
26 | public static String getIp() {
27 | return ipThreadLocal.get();
28 | }
29 |
30 | /**
31 | * Retrieve client ip address
32 | * 获取请求时的 客户端(浏览器) IP地址
33 | *
34 | * @param request HttpServletRequest
35 | * @return IP
36 | */
37 | public static String retrieveClientIp(HttpServletRequest request) {
38 | String ip = request.getHeader("x-forwarded-for");
39 | if (isUnAvailableIp(ip)) {
40 | ip = request.getHeader("Proxy-Client-IP");
41 | }
42 | if (isUnAvailableIp(ip)) {
43 | ip = request.getHeader("WL-Proxy-Client-IP");
44 | }
45 | if (isUnAvailableIp(ip)) {
46 | ip = request.getRemoteAddr();
47 | }
48 | return ip;
49 | }
50 |
51 | private static boolean isUnAvailableIp(String ip) {
52 | return StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip);
53 | }
54 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/context/OIDCApplicationContextAware.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.context;
2 |
3 |
4 | import myoidc.server.domain.shared.Application;
5 | import myoidc.server.domain.shared.BeanProvider;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.BeansException;
9 | import org.springframework.beans.factory.annotation.Value;
10 | import org.springframework.context.ApplicationContext;
11 | import org.springframework.context.ApplicationContextAware;
12 | import org.springframework.stereotype.Component;
13 |
14 | /**
15 | * 2018/03/22
16 | *
17 | *
18 | * @author Shengzhao Li
19 | */
20 | @Component
21 | public class OIDCApplicationContextAware implements ApplicationContextAware {
22 |
23 |
24 | private static final Logger LOG = LoggerFactory.getLogger(OIDCApplicationContextAware.class);
25 |
26 | @Value("${spring.application.name}")
27 | private String applicationName;
28 |
29 |
30 | @Value("${application.host}")
31 | private String applicationHost;
32 |
33 |
34 | public OIDCApplicationContextAware() {
35 | }
36 |
37 | @Override
38 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
39 | BeanProvider.initialize(applicationContext);
40 |
41 | if (LOG.isDebugEnabled()) {
42 | LOG.debug("Initialed BeanProvider from ApplicationContext: {}", applicationContext);
43 | }
44 | LOG.info("{} context initialized, Version: {}, applicationHost: {}\n", this.applicationName, Application.VERSION, this.applicationHost);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/context/OIDCServletContextAware.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.context;
2 |
3 |
4 | import myoidc.server.domain.shared.Application;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.stereotype.Component;
8 | import org.springframework.web.context.ServletContextAware;
9 |
10 | import javax.servlet.ServletContext;
11 |
12 | /**
13 | * 2020/5/7
14 | *
15 | * @author Shengzhao Li
16 | * @since 1.1.1
17 | */
18 | @Component
19 | public class OIDCServletContextAware implements ServletContextAware {
20 |
21 | private static final Logger LOG = LoggerFactory.getLogger(OIDCServletContextAware.class);
22 |
23 | public OIDCServletContextAware() {
24 | }
25 |
26 | @Override
27 | public void setServletContext(ServletContext servletContext) {
28 |
29 | //主版本号
30 | servletContext.setAttribute("mainVersion", Application.VERSION);
31 | LOG.debug("Initialed: {}, mainVersion: {}", this, Application.VERSION);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/context/SpringSecurityHolder.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.context;
2 |
3 |
4 | import myoidc.server.domain.security.OIDCUserDetails;
5 | import myoidc.server.domain.security.SecurityHolder;
6 | import org.springframework.security.core.Authentication;
7 | import org.springframework.security.core.context.SecurityContextHolder;
8 |
9 | /**
10 | * @author Shengzhao Li
11 | */
12 | public class SpringSecurityHolder implements SecurityHolder {
13 |
14 | @Override
15 | public OIDCUserDetails userDetails() {
16 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
17 | if (authentication == null) {
18 | return null;
19 | }
20 | Object principal = authentication.getPrincipal();
21 | if (principal instanceof OIDCUserDetails) {
22 | return (OIDCUserDetails) principal;
23 | }
24 | return null;
25 | }
26 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/MyOIDCController.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller;
2 |
3 | import myoidc.server.web.WebUtils;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.ui.Model;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 |
11 | import static myoidc.server.domain.shared.Application.host;
12 |
13 |
14 | /**
15 | * 2018/2/5
16 | *
17 | * @author Shengzhao Li
18 | */
19 | @Controller
20 | public class MyOIDCController {
21 |
22 |
23 | private static final Logger LOG = LoggerFactory.getLogger(MyOIDCController.class);
24 |
25 |
26 | /**
27 | * 首页
28 | */
29 | @RequestMapping(value = "/")
30 | public String index(Model model) {
31 | model.addAttribute("host", host());
32 | return "index";
33 | }
34 |
35 |
36 | //Go login
37 | @GetMapping(value = {"/login"})
38 | public String login(Model model) {
39 | LOG.debug("Go to login, IP: {}", WebUtils.getIp());
40 | model.addAttribute("host", host());
41 | return "login";
42 | }
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/admin/AdminRPController.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller.admin;
2 |
3 | import myoidc.server.service.OauthService;
4 | import myoidc.server.service.dto.OauthClientDetailsDto;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.ui.Model;
8 | import org.springframework.validation.BindingResult;
9 | import org.springframework.web.bind.annotation.*;
10 |
11 | import javax.validation.Valid;
12 | import java.util.List;
13 |
14 | import static myoidc.server.domain.shared.Application.host;
15 |
16 | /**
17 | * 2020/3/18
18 | *
19 | * 客户端[RP] 管理
20 | *
21 | * @author Shengzhao Li
22 | * @since 1.1.0
23 | */
24 | @Controller
25 | @RequestMapping("/admin/rp/")
26 | public class AdminRPController {
27 |
28 |
29 | @Autowired
30 | private OauthService oauthService;
31 |
32 |
33 | // RP 列表
34 | @GetMapping("list")
35 | public String rpList(String clientId, Model model) {
36 | List clientDetailsDtoList = oauthService.loadOauthClientDetailsDtos(clientId);
37 | model.addAttribute("dtoList", clientDetailsDtoList);
38 | model.addAttribute("clientId", clientId);
39 | return "admin/rp_list";
40 | }
41 |
42 |
43 | /**
44 | * Archive ,逻辑删除
45 | */
46 | @GetMapping("archive_client/{clientId}")
47 | public String archiveClient(@PathVariable("clientId") String clientId) {
48 | oauthService.archiveOauthClientDetails(clientId);
49 | return "redirect:../list";
50 | }
51 |
52 |
53 | /**
54 | * 添加客户端
55 | */
56 | @GetMapping("form/plus")
57 | public String addClient(Model model) {
58 | model.addAttribute("formDto", new OauthClientDetailsDto().initialized());
59 | return "admin/rp_form";
60 | }
61 |
62 |
63 | /**
64 | * 添加客户端
65 | */
66 | @PostMapping("form/plus")
67 | public String submitClient(@ModelAttribute("formDto") @Valid OauthClientDetailsDto formDto, BindingResult result, Model model) {
68 | if (result.hasErrors()) {
69 | return "admin/rp_form";
70 | }
71 | String clientId = oauthService.saveOAuthClientDetails(formDto);
72 | model.addAttribute("newClientId", clientId);
73 | return "redirect:../list";
74 | }
75 |
76 |
77 | /**
78 | * Test client
79 | */
80 | @RequestMapping("test_client/{clientId}")
81 | public String testClient(@PathVariable("clientId") String clientId, Model model) {
82 | OauthClientDetailsDto clientDetailsDto = oauthService.loadOauthClientDetailsDto(clientId);
83 | model.addAttribute("clientDetailsDto", clientDetailsDto);
84 | model.addAttribute("host", host());
85 | return "admin/rp_client_test";
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/admin/AdminUserController.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller.admin;
2 |
3 | import myoidc.server.service.UserService;
4 | import myoidc.server.service.dto.UserFormDto;
5 | import myoidc.server.service.dto.UserListDto;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.ui.Model;
9 | import org.springframework.validation.BindingResult;
10 | import org.springframework.web.bind.annotation.*;
11 |
12 | import javax.validation.Valid;
13 |
14 | /**
15 | * 2020/3/18
16 | *
17 | * 用户[EU] 管理
18 | *
19 | * @author Shengzhao Li
20 | * @since 1.1.0
21 | */
22 | @Controller
23 | @RequestMapping("/admin/user/")
24 | public class AdminUserController {
25 |
26 |
27 | @Autowired
28 | private UserService userService;
29 |
30 |
31 | /**
32 | * 用户列表
33 | */
34 | @GetMapping("list")
35 | public String list(UserListDto listDto, Model model) {
36 | listDto = userService.loadUserListDto(listDto);
37 | model.addAttribute("listDto", listDto);
38 | return "admin/user_list";
39 | }
40 |
41 |
42 | /**
43 | * 用户表单
44 | */
45 | @GetMapping(value = "form/plus")
46 | public String showForm(Model model) {
47 | model.addAttribute("formDto", new UserFormDto());
48 | return "admin/user_form";
49 | }
50 |
51 |
52 | /**
53 | * 用户表单
54 | */
55 | @PostMapping(value = "form/plus")
56 | public String submitRegisterClient(@ModelAttribute("formDto") @Valid UserFormDto formDto, BindingResult result, Model model) {
57 | if (result.hasErrors()) {
58 | return "admin/user_form";
59 | }
60 | String uuid = userService.saveUserForm(formDto);
61 | model.addAttribute("uuid", uuid).addAttribute("alert", "SaveOK");
62 | return "redirect:../list";
63 | }
64 |
65 |
66 | /**
67 | * archive
68 | */
69 | @GetMapping("archive/{uuid}")
70 | public String archive(@PathVariable String uuid, Model model) {
71 | boolean ok = userService.archiveUserByUuid(uuid);
72 | model.addAttribute("alert", ok ? "ArchivedOK" : "ArchivedFailed");
73 | return "redirect:../list";
74 | }
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/endpoint/DiscoveryEndpoint.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller.endpoint;
2 |
3 | import myoidc.server.infrastructure.oidc.OIDCUtils;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.RestController;
6 |
7 | import java.util.Arrays;
8 | import java.util.Collections;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | import static myoidc.server.Constants.ID_TOKEN;
13 | import static myoidc.server.Constants.OIDC_ALG;
14 | import static myoidc.server.domain.shared.Application.host;
15 | import static myoidc.server.infrastructure.oidc.OIDCUtils.SCOPE_OPENID;
16 | import static myoidc.server.infrastructure.oidc.OIDCUtils.SCOPE_READ;
17 | import static myoidc.server.infrastructure.oidc.OIDCUtils.SCOPE_WRITE;
18 |
19 | /**
20 | * 2020/3/11
21 | *
22 | * Discovery API
23 | * https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
24 | *
25 | * @author Shengzhao Li
26 | * @since 1.1.0
27 | */
28 | @RestController
29 | public class DiscoveryEndpoint {
30 |
31 |
32 | /**
33 | * https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest
34 | *
35 | * @return view
36 | * @throws Exception Exception
37 | */
38 | @GetMapping("/.well-known/openid-configuration")
39 | public Map configuration() throws Exception {
40 | Map model = new HashMap<>();
41 | String host = host();
42 | model.put("issuer", host);
43 | model.put("authorization_endpoint", OIDCUtils.authorizeEndpoint(host));
44 | model.put("token_endpoint", OIDCUtils.tokenEndpoint(host));
45 | model.put("userinfo_endpoint", OIDCUtils.userinfoEndpoint(host));
46 |
47 | model.put("jwks_uri", OIDCUtils.jwksURI(host));
48 | model.put("registration_endpoint", OIDCUtils.registrationEndpoint(host));
49 |
50 | model.put("scopes_supported", Arrays.asList(SCOPE_OPENID, SCOPE_READ, SCOPE_WRITE));
51 | model.put("grant_types_supported", OIDCUtils.GrantType.types());
52 | model.put("response_types_supported", Arrays.asList("token", "code", ID_TOKEN));
53 | //ALG:
54 | model.put("id_token_signing_alg_values_supported", Collections.singletonList(OIDC_ALG));
55 | // "pairwise",
56 | model.put("subject_types_supported", Arrays.asList("public"));
57 | model.put("claims_supported", Arrays.asList("sub", "aud", "scope", "iss", "exp", "iat", "client_id", "authorities", "user_name"));
58 | return model;
59 | }
60 |
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/endpoint/JWKSEndpoint.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller.endpoint;
2 |
3 | import myoidc.server.web.WebUtils;
4 | import org.jose4j.jwk.JsonWebKey;
5 | import org.jose4j.jwk.JsonWebKeySet;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.web.bind.annotation.GetMapping;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | /**
14 | * 2020/3/12
15 | *
16 | * JWKS URL API
17 | *
18 | * @author Shengzhao Li
19 | * @since 1.1.0
20 | */
21 | @RestController
22 | public class JWKSEndpoint {
23 |
24 |
25 | private static final Logger LOG = LoggerFactory.getLogger(JWKSEndpoint.class);
26 |
27 | @Autowired
28 | private JsonWebKeySet jsonWebKeySet;
29 |
30 |
31 | @GetMapping(value = "/public/jwks", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
32 | public String jwks() throws Exception {
33 | if (LOG.isDebugEnabled()) {
34 | LOG.debug("Call 'jwks' API from IP: {}", WebUtils.getIp());
35 | }
36 | return jsonWebKeySet.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/endpoint/RegistrationEndpoint.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller.endpoint;
2 |
3 | import myoidc.server.domain.shared.Application;
4 | import myoidc.server.infrastructure.oidc.OIDCUseScene;
5 | import myoidc.server.service.OauthService;
6 | import myoidc.server.service.SecurityService;
7 | import myoidc.server.service.dto.ClientRegistrationFormDto;
8 | import myoidc.server.service.dto.OauthClientDetailsDto;
9 | import myoidc.server.web.WebUtils;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.stereotype.Controller;
14 | import org.springframework.ui.Model;
15 | import org.springframework.validation.BindingResult;
16 | import org.springframework.web.bind.annotation.*;
17 |
18 | import javax.validation.Valid;
19 |
20 | /**
21 | * 2020/3/11
22 | *
23 | * Registration client API
24 | *
25 | * @author Shengzhao Li
26 | * @since 1.1.0
27 | */
28 | @Controller
29 | @RequestMapping("/public/")
30 | public class RegistrationEndpoint {
31 |
32 | private static final Logger LOG = LoggerFactory.getLogger(RegistrationEndpoint.class);
33 |
34 |
35 | @Autowired
36 | private SecurityService securityService;
37 |
38 |
39 | // 引导 注册
40 | @GetMapping("registration")
41 | public String preRegistration(Model model) {
42 | LOG.debug("{}|Pre registration, model: {}", WebUtils.getIp(), model);
43 | return "registration_pre";
44 | }
45 |
46 |
47 | /**
48 | * 开始注册 form
49 | *
50 | * @param useScene 使用场景, 默认为 WEB
51 | * @param model Model
52 | * @return view
53 | */
54 | @GetMapping("registration_form")
55 | public String registration(@RequestParam("scene") OIDCUseScene useScene, Model model) {
56 | ClientRegistrationFormDto formDto = new ClientRegistrationFormDto(useScene);
57 | model.addAttribute("formDto", formDto);
58 | return "registration_form";
59 | }
60 |
61 | /**
62 | * 注册客户端提交
63 | */
64 | @PostMapping("registration_form")
65 | public String submitRegistration(@ModelAttribute("formDto") @Valid ClientRegistrationFormDto formDto, BindingResult result, Model model) {
66 | if (result.hasErrors()) {
67 | return "registration_form";
68 | }
69 | OauthClientDetailsDto clientDetailsDto = securityService.saveClientRegistrationForm(formDto);
70 | model.addAttribute("clientDetailsDto", clientDetailsDto);
71 | model.addAttribute("host", Application.host());
72 | return "registration_success";
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/endpoint/UserInfoEndpoint.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller.endpoint;
2 |
3 | import myoidc.server.service.SecurityService;
4 | import myoidc.server.service.dto.UserJsonDto;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RestController;
9 |
10 | /**
11 | * 2020/3/11
12 | *
13 | * UserInfo API
14 | *
15 | * https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
16 | *
17 | * @author Shengzhao Li
18 | * @since 1.1.0
19 | */
20 | @RestController
21 | @RequestMapping("/api/")
22 | public class UserInfoEndpoint {
23 |
24 |
25 | @Autowired
26 | private SecurityService securityService;
27 |
28 |
29 | @GetMapping("userinfo")
30 | public UserJsonDto userinfo() {
31 | return securityService.loadCurrentUserJsonDto();
32 | }
33 |
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/resource/MobileController.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller.resource;
2 |
3 |
4 | import myoidc.server.service.SecurityService;
5 | import myoidc.server.service.dto.OAuthResourceDto;
6 | import myoidc.server.service.dto.UserJsonDto;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Controller;
9 | import org.springframework.web.bind.annotation.GetMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseBody;
12 |
13 | import static myoidc.server.Constants.RESOURCE_ID;
14 |
15 | /**
16 | * Mobile Resource API
17 | *
18 | * @author Shengzhao Li
19 | */
20 | @Controller
21 | @RequestMapping("/m/")
22 | public class MobileController {
23 |
24 |
25 | @Autowired
26 | private SecurityService securityService;
27 |
28 |
29 | @GetMapping("dashboard")
30 | @ResponseBody
31 | public OAuthResourceDto dashboard() {
32 | return new OAuthResourceDto(RESOURCE_ID, "Just mobile-Resource");
33 | }
34 |
35 | @GetMapping("user_info")
36 | @ResponseBody
37 | public UserJsonDto userInfo() {
38 | return securityService.loadCurrentUserJsonDto();
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/controller/resource/UnityController.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.controller.resource;
2 |
3 |
4 | import myoidc.server.service.SecurityService;
5 | import myoidc.server.service.dto.OAuthResourceDto;
6 | import myoidc.server.service.dto.UserJsonDto;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Controller;
9 | import org.springframework.web.bind.annotation.GetMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseBody;
12 |
13 | import static myoidc.server.Constants.RESOURCE_ID;
14 |
15 | /**
16 | * Unity Resource API
17 | *
18 | * @author Shengzhao Li
19 | */
20 | @Controller
21 | @RequestMapping("/unity/")
22 | public class UnityController {
23 |
24 |
25 | @Autowired
26 | private SecurityService securityService;
27 |
28 |
29 | @GetMapping("dashboard")
30 | @ResponseBody
31 | public OAuthResourceDto dashboard() {
32 | return new OAuthResourceDto(RESOURCE_ID, "Just unity-Resource");
33 | }
34 |
35 | @GetMapping("user_info")
36 | @ResponseBody
37 | public UserJsonDto userInfo() {
38 | return securityService.loadCurrentUserJsonDto();
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/java/myoidc/server/web/filter/ExtCharacterEncodingFilter.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.web.filter;
2 |
3 |
4 | import myoidc.server.domain.shared.Application;
5 | import myoidc.server.web.WebUtils;
6 | import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
7 |
8 | import javax.servlet.FilterChain;
9 | import javax.servlet.ServletException;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.io.IOException;
13 |
14 | /**
15 | * Wrap the spring CharacterEncodingFilter, add retrieve client ip action
16 | *
17 | *
18 | * 扩展 默认的 CharacterEncodingFilter, 添加对IP 地址的获取
19 | *
20 | * @author Shengzhao Li
21 | */
22 | public class ExtCharacterEncodingFilter extends OrderedCharacterEncodingFilter {
23 |
24 |
25 | public ExtCharacterEncodingFilter() {
26 | setEncoding(Application.ENCODING);
27 | }
28 |
29 | @Override
30 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
31 | throws ServletException, IOException {
32 |
33 | persistIp(request);
34 | super.doFilterInternal(request, response, filterChain);
35 |
36 | }
37 |
38 | /**
39 | * 将IP地址 放置在 ThreadLocal 中
40 | */
41 | private void persistIp(HttpServletRequest request) {
42 | final String clientIp = WebUtils.retrieveClientIp(request);
43 | WebUtils.setIp(clientIp);
44 | }
45 |
46 |
47 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | # MyOIDC -Server V-1.1.0
2 | #
3 | spring.application.name=MyOIDC[Server]
4 | spring.main.allow-bean-definition-overriding=true
5 | spring.jmx.enabled=false
6 | #
7 | #JDBC
8 | #Connection
9 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
10 | spring.datasource.url=jdbc:mysql://localhost:3306/myoidc_server?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
11 | spring.datasource.username=andaily
12 | spring.datasource.password=andaily
13 | #Datasource properties
14 | spring.datasource.type=com.zaxxer.hikari.HikariDataSource
15 | spring.datasource.hikari.maximum-pool-size=20
16 | spring.datasource.hikari.minimum-idle=2
17 | #JPA
18 | spring.data.jpa.repositories.enabled=false
19 | spring.jpa.open-in-view=false
20 | #
21 | # MVC
22 | spring.mvc.ignore-default-model-on-redirect=false
23 | spring.http.encoding.enabled=true
24 | spring.http.encoding.charset=UTF-8
25 | spring.http.encoding.force=true
26 | #
27 | #THYMELEAF (ThymeleafAutoConfiguration)
28 | #
29 | #spring.thymeleaf.prefix=/WEB-INF/view/
30 | #spring.thymeleaf.suffix=.html
31 | #spring.thymeleaf.mode=HTML5
32 | spring.thymeleaf.encoding=UTF-8
33 | # ;charset= is added
34 | # set to false for hot refresh
35 | spring.thymeleaf.cache=false
36 | #
37 | # Logging INFO
38 | #
39 | logging.level.root=INFO
40 | #logging.config=classpath:log4j2.xml
41 | #logging.level.org.springframework.transaction.interceptor=TRACE
42 | #
43 | # Security
44 | #
45 | #
46 | #Tomcat Server Config
47 | #
48 | server.tomcat.accesslog.enabled=true
49 | server.tomcat.uri-encoding=UTF-8
50 | server.port=8086
51 | #
52 | # gzip, compression
53 | server.compression.enabled=true
54 | server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
55 | server.compression.min-response-size=1024
56 | #
57 | #Application host url, end by '/'
58 | application.host=http://localhost:${server.port}/
59 |
60 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/jwks.json:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "alg": "RS256",
5 | "d": "PvBAngE3kkTnD3yDKo3wCvHJHm20kb9a0FVGLd0s2Y0E_3H2XnZC8-2zPhN6AQTjPhohSDCew20gzm76lyOvMqRiUP2Zpaopa1d2fGvNIQSdM07yKa6EivEYxqPQxa5esoZnexgnb9fom70I8n5OQRNQikwu-az26CsHX2zWMRodzSdN5CXHvb1PV09DmH8azTYwoMElPIqmcTfxiRw2Ov5ucmXXngKRFJgvfUgKd7v4ScBX7sQoQEjWEtt7ta0WvL3Ar5E1RAW4aHxuubZ6AtloxWCf17AAKw03dfP5RDm5TDmgm2B635ecJ7fTvneFmg8W_fdMTPRfBlCGNBp3wQ",
6 | "e": "AQAB",
7 | "n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw",
8 | "kty": "RSA",
9 | "kid": "rsa1"
10 | },
11 | {
12 | "kty": "RSA",
13 | "kid": "myoidc-keyid",
14 | "use": "sig",
15 | "alg": "RS256",
16 | "n": "n6X4_VZSQjxmSqBqmIq5ZbaLynXPP3yCOF2xE250NaYLferU8LX3xAvuNLnZkaUH-4cnr_JuSlN_7JIAwAd5oLHSuSByPcxSJ95uGniDji22s-yQ19rqZCQHLmJwg3WZpWPN-HmwxPOFNlkW_2ETjqMzS-3kGduz-IPfebwNbVFu6RglHT_V6IyaDUbSvV80AAQ7R8Y6xBvu25ZSniu3JHj2u8AtScJgiOqfsImsaCABdmUO4LtMzB1V7pafH-_puRWYCl5_uaYYPMxv-EOonPCyTlzJtC6ZeiiI4LNtxWwEamRyTS0xX8Czt3s5mRW2q6pgMZQsqlL64Df8MDuFpQ",
17 | "e": "AQAB",
18 | "d": "E92YRRXnuHxBkkmx2fdxKHn1nSTZvCGnJpJqBWv6I-7cgTemdal_AjMl2gPCUgBCJQdlZdx54t_PDEYCt-J2PQvDl-u0q4HwOyvPcZXLcPa5RFxMjb-c6QceqaPwMjuA-faYW7Hw0CEpU2D0nqSaxWYDbRBWEO2o0GTAeypuVUrZXGilOLjal68Tho8ZYbmyXsEvEdqCob_iUe6q4c2x0amMmn2ot3bKKqdjbVXMjVfEqHHMPMdnVmrr_yfTUlXN3ZT4Ypp7wDrAVs7pfbvrCKWzLQYlbYNjZeBoKNcGabAA7WuNGxWvi3971gLSdYwRw4TngOweIhVW8kxiiA77QQ",
19 | "p": "2R_SdLqd7d7hVJTAVY4Twx8j7VQq6-TTMVcyD_YLeBGvlkngpSz7NSQu1LTYGEHa_CzeCOFmKgtuLZ84zyS_wUxgF3AH0VD-xNZSAaHfzWXAwLmezYzGBXXF0ho8qpbf2aTNZZx2n5z0cb0loitAfmfrsd9XU226nXpPAgV-gTE",
20 | "q": "vDup5zcW9NwxVs9-C-W1uwL7TpQIKNk9oBvbfgD6XkwIn3JmCfny2Nm-paK45YM169JhnUml7z6On2Bq81rNtPwkqWTp9d2SfsQkuNddtfeYi_FulLqMLeQvCr2TAdFE-4uYKcU_-5u21oomnVm5vgGs8aFzd_J-57i-GfPxjrU",
21 | "dp": "UwpZqm1JQ5WvpnKx0MbjBghd7EH5nHjK0R8hNXuLzWMuPZOJyIKYnS12f8GeuEBPqYzbapgSQ9hVTjuMNaU_dYVpZu1hAAwzNEMn4BnyB5N4Ef2sH79MaQAvJXkFZNUJTis6pzcdI1SbJPkLcKeMJgxG16OsuWrJKbuChiplxLE",
22 | "dq": "aQYJGD6-ikRJKxx-QXkbWoqhWQhzPQdowOqKHtXA29gkf4I-uJZDDwb-vj_6VeRNs5Qgbrfm44PN49LSGZGycKa2deUePNYxpJUfwBo56QuKi5pbjpQ_HmPQc3eujDcM_CS486Vgu6v36eAPB4BGiGM68V6ZpHUipXuIZcacInk",
23 | "qi": "bvay2Ej4FIYrFpD0zW-xEpHoPxXmNJRyR4rL4SGVq-ILghfVqfTQszI2MUnpubcUAUsqYYZUvvemfust35eYiSaYWzUDGsjmUWhZDD8VTKEyxbWwya7GztarLMud2LGn76a41zyStU46g84G1ZPNcZTK_1DIR0_BpayN44jj3kk"
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/public/bootstrap/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-server/src/main/resources/public/bootstrap/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/public/bootstrap/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-server/src/main/resources/public/bootstrap/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/public/bootstrap/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-server/src/main/resources/public/bootstrap/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/public/bootstrap/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-server/src/main/resources/public/bootstrap/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-server/src/main/resources/public/favicon.ico
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/public/images/oidc-sm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-server/src/main/resources/public/images/oidc-sm.png
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/public/images/openid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/myoidc-server/src/main/resources/public/images/openid.png
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/templates/admin/user_list.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 | 用户[EU] . MyOIDC
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
用户[EU]
18 |
19 |
27 |
28 |
29 |
30 |
31 | 账号 |
32 | 权限 |
33 | 电话 |
34 | 邮箱 |
35 | 创建时间 |
36 | 操作 |
37 |
38 |
39 |
40 |
41 | unity |
42 | [UNITY] |
43 | 133... |
44 | xxx@xxx.com |
45 | 2019-xxx |
46 |
47 | archive
49 | ...
50 | |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/templates/fragment/footer.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | Fragment Footer
7 |
8 |
9 |
10 |
11 |
12 |
© 2017-2020 MyOIDC
14 | V
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/templates/fragment/header.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | Fragment Header
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/templates/registration_form.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 注册 . MyOIDC
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
![Logo]()
19 |
20 |
请填写注册信息
21 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/templates/registration_pre.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 注册 . MyOIDC
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
![Logo]()
19 |
20 |
请选择注册使用场景
21 |
42 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/myoidc-server/src/main/resources/templates/registration_success.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 注册 . MyOIDC
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
![Logo]()
19 |
20 |
注册成功!
21 |
请保存以下注册信息
22 |
23 |
24 | - ClientId
25 | - xxx
26 | - ClientSecret
27 | - xxx
28 | - Redirect Uri
29 | - xxx
30 | - Scope
31 | - xxx
32 | - GrantType
33 | - xxx
34 | - Discovery-Endpoint
35 | - xxx
36 |
37 |
38 |
主页
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/ContextTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server;
2 |
3 |
4 | import myoidc.server.domain.security.OIDCUserDetails;
5 | import myoidc.server.domain.security.SecurityUtils;
6 | import myoidc.server.domain.shared.BeanProvider;
7 | import myoidc.server.web.context.SpringSecurityHolder;
8 | import org.junit.runner.RunWith;
9 | import org.springframework.boot.test.context.SpringBootTest;
10 | import org.springframework.test.context.TestPropertySource;
11 | import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
12 | import org.springframework.test.context.junit4.SpringRunner;
13 | import org.springframework.test.context.transaction.BeforeTransaction;
14 |
15 |
16 | /**
17 | * @author Shengzhao Li
18 | */
19 | @RunWith(SpringRunner.class)
20 | @SpringBootTest
21 | @TestPropertySource(locations = "classpath:application-test.properties")
22 | public abstract class ContextTest extends AbstractTransactionalJUnit4SpringContextTests {
23 |
24 |
25 | @BeforeTransaction
26 | public void before() throws Exception {
27 | BeanProvider.initialize(applicationContext);
28 | SecurityUtils securityUtils = new SecurityUtils();
29 | securityUtils.setSecurityHolder(new SpringSecurityHolder() {
30 | @Override
31 | public OIDCUserDetails userDetails() {
32 | return null;
33 | }
34 | });
35 | }
36 |
37 |
38 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/JwkTokenStoreTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server;
2 |
3 | import org.junit.Ignore;
4 | import org.junit.Test;
5 | import org.springframework.security.oauth2.common.OAuth2AccessToken;
6 | import org.springframework.security.oauth2.provider.OAuth2Authentication;
7 | import org.springframework.security.oauth2.provider.token.store.jwk.JwkTokenStore;
8 |
9 | import java.util.List;
10 |
11 | import static org.junit.Assert.assertNotNull;
12 |
13 | /**
14 | * 2020/3/13
15 | *
16 | * @author Shengzhao Li
17 | */
18 | public class JwkTokenStoreTest {
19 |
20 |
21 | @Test
22 | @Ignore
23 | public void test() throws Exception {
24 |
25 | String jwkSetUrl = "http://localhost:8080/myoidc-server/public/jwks";
26 | JwkTokenStore tokenStore = new JwkTokenStore(jwkSetUrl);
27 |
28 | assertNotNull(tokenStore);
29 |
30 | String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImF1ZCI6WyJteW9pZGMtcmVzb3VyY2UiXSwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJvcGVuaWQiXSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL215b2lkYy1zZXJ2ZXIvIiwiZXhwIjoxNTg0MDczNDc5LCJpYXQiOjE1ODQwMzAyNzksImF1dGhvcml0aWVzIjpbIlJPTEVfTU9CSUxFIiwiUk9MRV9BRE1JTiIsIlJPTEVfVVNFUiIsIlJPTEVfVU5JVFkiXSwianRpIjoiZmU3MGY3NjktZTIxYi00NzczLWJlN2EtYTQwMGE0MzY2YWYxIiwiY2xpZW50X2lkIjoibW9iaWxlLWNsaWVudCJ9.L7nETF-NDQcJV0YiZVbT25mSF-LPWq7oLoCPR1N5glCnB_wZO3i1wfIbVqo0HAtcTHwiLeRkyPBCDn2BTEdotQqyTxazAloV2dCej_9b2a341mAzqpsVHQygkYdMVNW5Gfo4QaBMab_PCNAeO5w0BRHhlCOVi-WMmvzoaZrPyFaLS0sURMqpCTjvrt7e_XkkCOoY-0WcRbXmWGmgB9Kil0NVA4j67pUVFMMP2sgzoCNmmYXK70vVLTzSRjodbEQqsyS9Q6sU7E28hT8Vu21GVyHIL0S0p1tK5JKXPerb-UGWBXSV90LEynTe0hU5IJxW-urN6YaoxcZfy6eGm8jI9w";
31 | // OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
32 | // assertNotNull(oAuth2AccessToken);
33 |
34 | OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(token);
35 | assertNotNull(oAuth2Authentication);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/MyOIDCServerApplicationTests.java:
--------------------------------------------------------------------------------
1 | package myoidc.server;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.TestPropertySource;
7 | import org.springframework.test.context.junit4.SpringRunner;
8 |
9 | @RunWith(SpringRunner.class)
10 | @SpringBootTest
11 | @TestPropertySource(locations = "classpath:application-test.properties")
12 | public class MyOIDCServerApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/configuration/SecurityConfigurationTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.configuration;
2 |
3 | import org.junit.Test;
4 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
5 |
6 | import static org.junit.Assert.*;
7 |
8 | /**
9 | * 2018/3/22
10 | *
11 | * @author Shengzhao Li
12 | */
13 | public class SecurityConfigurationTest {
14 | @Test
15 | public void passwordEncoder() throws Exception {
16 |
17 |
18 | BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
19 | final String rawPassword = "mobile";
20 | final String admin = passwordEncoder.encode(rawPassword);
21 |
22 | assertNotNull(admin);
23 |
24 | // System.out.println(rawPassword + " --> " + admin);
25 |
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/domain/shared/UUIDGeneratorTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.domain.shared;
2 |
3 | import org.junit.Test;
4 |
5 | /**
6 | * 2018/3/22
7 | *
8 | * @author Shengzhao Li
9 | */
10 | public class UUIDGeneratorTest {
11 |
12 |
13 | @Test
14 | public void generate() throws Exception {
15 |
16 | System.out.println(UUIDGenerator.generate());
17 |
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/AbstractRepositoryTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 | import myoidc.server.ContextTest;
4 | import org.junit.Test;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 |
7 | import javax.persistence.EntityManager;
8 | import javax.persistence.EntityManagerFactory;
9 |
10 | import static org.junit.Assert.assertNotNull;
11 |
12 | /**
13 | * 2018/3/22
14 | *
15 | * @author Shengzhao Li
16 | */
17 | public class AbstractRepositoryTest extends ContextTest {
18 |
19 |
20 | @Autowired
21 | private EntityManagerFactory entityManagerFactory;
22 |
23 |
24 | protected EntityManager entityManager() {
25 | return entityManagerFactory.createEntityManager();
26 | }
27 |
28 |
29 | protected void flush() {
30 | EntityManager entityManager = entityManager();
31 | entityManager.flush();
32 | entityManager.clear();
33 | }
34 |
35 |
36 | @Test
37 | public void test() {
38 | assertNotNull(entityManagerFactory);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/Auth0JwtTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 |
4 | import com.auth0.jwt.JWT;
5 | import com.auth0.jwt.JWTVerifier;
6 | import com.auth0.jwt.algorithms.Algorithm;
7 | import com.auth0.jwt.interfaces.DecodedJWT;
8 | import org.junit.Test;
9 |
10 | import java.security.KeyPair;
11 | import java.security.KeyPairGenerator;
12 | import java.security.PrivateKey;
13 | import java.security.PublicKey;
14 | import java.security.interfaces.RSAPrivateKey;
15 | import java.security.interfaces.RSAPublicKey;
16 |
17 | import static org.junit.Assert.assertNotNull;
18 |
19 | /**
20 | * 2018/5/30
21 | *
22 | * OAuth0 jwt
23 | *
24 | * @author Shengzhao Li
25 | */
26 | public class Auth0JwtTest {
27 |
28 |
29 | /**
30 | * Test JWT
31 | *
32 | * @throws Exception Exception
33 | */
34 | @Test
35 | public void jwt() throws Exception {
36 |
37 | // RSA keyPair Generator
38 | final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
39 | /*
40 | * 长度 至少 1024, 建议 2048
41 | */
42 | final int keySize = 2048;
43 | keyPairGenerator.initialize(keySize);
44 |
45 | final KeyPair keyPair = keyPairGenerator.genKeyPair();
46 |
47 |
48 | final PublicKey publicKey = keyPair.getPublic();
49 | final PrivateKey privateKey = keyPair.getPrivate();
50 |
51 |
52 | // gen id_token
53 | final Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) publicKey, (RSAPrivateKey) privateKey);
54 |
55 | final String idToken = JWT.create().withJWTId("jwt-id").withAudience("audience").withSubject("subject").sign(algorithm);
56 |
57 | assertNotNull(idToken);
58 | System.out.println(idToken);
59 |
60 |
61 | //verify
62 | // final DecodedJWT decodedJWT = JWT.decode(idToken);
63 | // System.out.println("id_token -> header: " + decodedJWT.getHeader());
64 | // System.out.println("id_token -> payload: " + decodedJWT.getPayload());
65 | // System.out.println("id_token -> token: " + decodedJWT.getToken());
66 | // System.out.println("id_token -> signature: " + decodedJWT.getSignature());
67 |
68 |
69 | final JWTVerifier verifier = JWT.require(algorithm).build();
70 | final DecodedJWT verify = verifier.verify(idToken);
71 |
72 | assertNotNull(verify);
73 | System.out.println(verify);
74 |
75 |
76 | // final Algorithm none = Algorithm.none();
77 |
78 | }
79 |
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/JJwtTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 |
4 | import io.jsonwebtoken.*;
5 | import org.apache.commons.lang3.time.DateUtils;
6 | import org.junit.Test;
7 |
8 | import java.security.KeyPair;
9 | import java.security.KeyPairGenerator;
10 | import java.security.PrivateKey;
11 | import java.security.PublicKey;
12 | import java.util.Date;
13 |
14 | import static org.junit.Assert.assertNotNull;
15 |
16 | /**
17 | * 2018/5/30
18 | *
19 | *
20 | * Test JJWT lib
21 | *
22 | * @author Shengzhao Li
23 | */
24 | public class JJwtTest {
25 |
26 |
27 | @Test
28 | public void idToken() throws Exception {
29 |
30 | // RSA keyPair Generator
31 | final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
32 | /*
33 | * 长度 至少 1024, 建议 2048
34 | */
35 | final int keySize = 2048;
36 | keyPairGenerator.initialize(keySize);
37 |
38 | final KeyPair keyPair = keyPairGenerator.genKeyPair();
39 |
40 | final PrivateKey privateKey = keyPair.getPrivate();
41 |
42 | // gen id_token
43 | final Date exp = DateUtils.addMinutes(new Date(), 5);
44 | final JwtBuilder jwtBuilder = Jwts.builder().setId("jti").setSubject("sub").setExpiration(exp).signWith(SignatureAlgorithm.RS512, privateKey);
45 | final String idToken = jwtBuilder.compact();
46 |
47 |
48 | assertNotNull(idToken);
49 | System.out.println(idToken);
50 |
51 |
52 | // verify
53 |
54 | final PublicKey publicKey = keyPair.getPublic();
55 | // final Jwt jwt = Jwts.parser().parse(idToken);
56 | final JwtParser parser = Jwts.parser();
57 | final Jwt jwt = parser.setSigningKey(publicKey).parse(idToken);
58 |
59 | assertNotNull(jwt);
60 | System.out.println(jwt.getHeader());
61 | System.out.println(jwt.getBody());
62 |
63 |
64 | }
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/JsonWebKeySetTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 | import com.google.common.base.Charsets;
4 | import com.google.common.io.CharStreams;
5 | import org.jose4j.jwk.JsonWebKey;
6 | import org.jose4j.jwk.JsonWebKeySet;
7 | import org.jose4j.jws.AlgorithmIdentifiers;
8 | import org.jose4j.jws.JsonWebSignature;
9 | import org.jose4j.jwt.JwtClaims;
10 | import org.junit.Test;
11 |
12 | import java.io.InputStream;
13 | import java.io.InputStreamReader;
14 |
15 | import static org.junit.Assert.assertNotNull;
16 |
17 | /**
18 | * 2020/6/3
19 | *
20 | * @author Shengzhao Li
21 | * @since 1.1.1
22 | */
23 | public class JsonWebKeySetTest {
24 |
25 |
26 | //RSA
27 | @Test
28 | public void keySet() throws Exception {
29 |
30 | JsonWebKeySet jwkSet;
31 | try (InputStream is = getClass().getClassLoader().getResourceAsStream("jwks_rsa.json")) {
32 | String keyJson = CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8));
33 | jwkSet = new JsonWebKeySet(keyJson);
34 | }
35 |
36 | JsonWebKey jsonWebKey = jwkSet.getJsonWebKeys().get(0);
37 | assertNotNull(jsonWebKey);
38 |
39 |
40 | }
41 |
42 |
43 | //ECC
44 | @Test
45 | public void keyECCSet() throws Exception {
46 |
47 | JsonWebKeySet jwkSet;
48 | try (InputStream is = getClass().getClassLoader().getResourceAsStream("jwks_ec.json")) {
49 | String keyJson = CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8));
50 | jwkSet = new JsonWebKeySet(keyJson);
51 | }
52 |
53 | JsonWebKey jsonWebKey = jwkSet.getJsonWebKeys().get(0);
54 | assertNotNull(jsonWebKey);
55 |
56 |
57 | }
58 |
59 |
60 | //OCT
61 | @Test
62 | public void keyOCTSet() throws Exception {
63 |
64 | JsonWebKeySet jwkSet;
65 | try (InputStream is = getClass().getClassLoader().getResourceAsStream("jwks_oct.json")) {
66 | String keyJson = CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8));
67 | jwkSet = new JsonWebKeySet(keyJson);
68 | }
69 |
70 | JsonWebKey jsonWebKey = jwkSet.getJsonWebKeys().get(0);
71 | assertNotNull(jsonWebKey);
72 |
73 |
74 | JsonWebSignature jws = new JsonWebSignature();
75 | jws.setKey(jsonWebKey.getKey());
76 |
77 | JwtClaims claims = new JwtClaims();
78 | claims.setGeneratedJwtId();
79 | claims.setIssuedAtToNow();
80 | claims.setSubject("subject");
81 | jws.setPayload(claims.toJson());
82 |
83 | jws.setKeyIdHeaderValue(jsonWebKey.getKeyId());
84 | jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
85 |
86 | String idToken = jws.getCompactSerialization();
87 | assertNotNull(idToken);
88 | // System.out.println(idToken);
89 |
90 | }
91 |
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/PasswordHandlerTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * 2020/3/22
9 | *
10 | * @author Shengzhao Li
11 | */
12 | public class PasswordHandlerTest {
13 |
14 |
15 | @Test
16 | public void randomPassword() {
17 |
18 | String s = PasswordHandler.randomPassword();
19 | assertNotNull(s);
20 | assertEquals(s.length(), 12);
21 | System.out.println(s);
22 |
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/PrimeJwtTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 |
4 | import org.junit.Test;
5 | import org.primeframework.jwt.JWTUtils;
6 | import org.primeframework.jwt.domain.JWT;
7 | import org.primeframework.jwt.domain.RSAKeyPair;
8 | import org.primeframework.jwt.hmac.HMACSigner;
9 | import org.primeframework.jwt.hmac.HMACVerifier;
10 | import org.primeframework.jwt.rsa.RSASigner;
11 | import org.primeframework.jwt.rsa.RSAVerifier;
12 |
13 | import static org.junit.Assert.assertEquals;
14 | import static org.junit.Assert.assertNotNull;
15 |
16 | /**
17 | * 2018/6/2
18 | *
19 | * Testing
20 | * https://github.com/inversoft/prime-jwt
21 | *
22 | * @author Shengzhao Li
23 | */
24 | public class PrimeJwtTest {
25 |
26 |
27 | /**
28 | * Test RSA 非对称算法
29 | *
30 | * @throws Exception Exception
31 | */
32 | @Test
33 | public void jwtRSA() throws Exception {
34 |
35 |
36 | // keypair
37 | final RSAKeyPair rsaKeyPair = JWTUtils.generate2048RSAKeyPair();
38 |
39 | System.out.println("PublicKey: " + rsaKeyPair.publicKey);
40 | System.out.println("PrivateKey: " + rsaKeyPair.privateKey);
41 |
42 |
43 | // final RSAPublicKey publicKey = RSAUtils.getPublicKeyFromPEM(rsaKeyPair.publicKey);
44 | // final RSAPrivateKey privateKey = RSAUtils.getPrivateKeyFromPEM(rsaKeyPair.privateKey);
45 |
46 | // generate
47 | final RSASigner rsaSigner = RSASigner.newSHA256Signer(rsaKeyPair.privateKey);
48 | final JWT jwt = new JWT().setSubject("subject").setAudience("audi").setUniqueId("uid-id");
49 | final String idToken = JWT.getEncoder().encode(jwt, rsaSigner);
50 |
51 | assertNotNull(idToken);
52 | System.out.println(idToken);
53 |
54 | //verify
55 | final RSAVerifier rsaVerifier = RSAVerifier.newVerifier(rsaKeyPair.publicKey);
56 | final JWT decode = JWT.getDecoder().decode(idToken, rsaVerifier);
57 |
58 | assertNotNull(decode);
59 | assertEquals(decode.audience, "audi");
60 |
61 | }
62 |
63 | /**
64 | * Test HMAC, 对称算法
65 | *
66 | * @throws Exception Exception
67 | */
68 | @Test
69 | public void jwtHMAC() throws Exception {
70 |
71 |
72 | // secret
73 | final String secret = JWTUtils.generateSHA256HMACSecret();
74 |
75 | System.out.println("secret: " + secret);
76 |
77 |
78 | // generate
79 |
80 | final JWT jwt = new JWT().setSubject("subject").setAudience("audi").setUniqueId("uid-id");
81 | final HMACSigner hmacSigner = HMACSigner.newSHA256Signer(secret);
82 | final String idToken = JWT.getEncoder().encode(jwt, hmacSigner);
83 |
84 | assertNotNull(idToken);
85 | System.out.println(idToken);
86 |
87 | //verify
88 | final HMACVerifier hmacVerifier = HMACVerifier.newVerifier(secret);
89 | final JWT decode = JWT.getDecoder().decode(idToken, hmacVerifier);
90 |
91 | assertNotNull(decode);
92 | assertEquals(decode.audience, "audi");
93 |
94 | }
95 |
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/RandomUtilsTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 |
4 | import org.junit.Test;
5 |
6 | import static org.junit.Assert.*;
7 |
8 | /**
9 | * @author Shengzhao Li
10 | */
11 | public class RandomUtilsTest {
12 |
13 | @Test
14 | public void testRandomText() throws Exception {
15 |
16 | final String random = RandomUtils.randomText();
17 | assertNotNull(random);
18 | assertEquals(random.length(), 32);
19 | // System.out.println(random);
20 |
21 | }
22 |
23 | @Test
24 | public void testRandomNumber() throws Exception {
25 |
26 | final String number = RandomUtils.randomNumber();
27 | assertNotNull(number);
28 | assertEquals(number.length(), 32);
29 | // System.out.println(number);
30 |
31 | }
32 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/VertxAuthJwtTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure;
2 |
3 |
4 | import io.vertx.core.json.JsonObject;
5 | import io.vertx.ext.jwt.JWK;
6 | import io.vertx.ext.jwt.JWT;
7 | import io.vertx.ext.jwt.JWTOptions;
8 | import org.junit.Test;
9 |
10 | import java.security.KeyPair;
11 | import java.security.KeyPairGenerator;
12 | import java.security.PrivateKey;
13 | import java.security.PublicKey;
14 | import java.util.Base64;
15 |
16 | import static org.junit.Assert.assertEquals;
17 | import static org.junit.Assert.assertNotNull;
18 |
19 | /**
20 | * 2018/6/2
21 | *
22 | * Test
23 | * https://github.com/vert-x3/vertx-auth
24 | *
25 | * @author Shengzhao Li
26 | */
27 | public class VertxAuthJwtTest {
28 |
29 |
30 | /**
31 | * Generate/ Verify
32 | *
33 | * @throws Exception Exception
34 | */
35 | @Test
36 | public void jwt() throws Exception {
37 |
38 |
39 | // RSA keyPair Generator
40 | final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
41 | /*
42 | * 长度 至少 1024, 建议 2048
43 | */
44 | final int keySize = 2048;
45 | keyPairGenerator.initialize(keySize);
46 |
47 | final KeyPair keyPair = keyPairGenerator.genKeyPair();
48 | //公钥
49 | final PublicKey publicKey = keyPair.getPublic();
50 | //私钥
51 | final PrivateKey privateKey = keyPair.getPrivate();
52 |
53 |
54 | final String pemPub = Base64.getEncoder().encodeToString(publicKey.getEncoded());
55 | final String pemSec = Base64.getEncoder().encodeToString(privateKey.getEncoded());
56 |
57 |
58 | //generate
59 | final String algorithm = "RS256";
60 | JWK jwk = new JWK(algorithm, pemPub, pemSec);
61 | final JWT jwt = new JWT().addJWK(jwk);
62 |
63 |
64 | JsonObject payload = new JsonObject();
65 | payload.put("appid", "appid");
66 |
67 | JWTOptions options = new JWTOptions();
68 | options.setAlgorithm(algorithm);
69 | options.setSubject("subject");
70 |
71 | String idToken = jwt.sign(payload, options);
72 |
73 | assertNotNull(idToken);
74 | System.out.println(idToken);
75 |
76 |
77 | //verify
78 | JWK jwk2 = new JWK(algorithm, pemPub, pemSec);
79 | final JWT jwtVerify = new JWT().addJWK(jwk2);
80 |
81 | final JsonObject decode = jwtVerify.decode(idToken);
82 | assertNotNull(decode);
83 | assertEquals(decode.getString("appid"), "appid");
84 |
85 | }
86 |
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/jdbc/OauthRepositoryJdbcTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure.jdbc;
2 |
3 | import myoidc.server.domain.oauth.OauthClientDetails;
4 | import myoidc.server.infrastructure.AbstractRepositoryTest;
5 | import org.junit.Test;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 |
8 | import java.util.List;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * 2020/3/19
14 | *
15 | * @author Shengzhao Li
16 | */
17 | public class OauthRepositoryJdbcTest extends AbstractRepositoryTest {
18 |
19 |
20 | @Autowired
21 | private OauthRepositoryJdbc repositoryJdbc;
22 |
23 |
24 | @Test
25 | public void findAllOauthClientDetails() {
26 |
27 | List list = repositoryJdbc.findAllOauthClientDetails("client_id");
28 | assertTrue(list.isEmpty());
29 | }
30 |
31 |
32 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/jpa/UserRepositoryHibernateTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure.jpa;
2 |
3 | import myoidc.server.domain.user.Privilege;
4 | import myoidc.server.domain.user.User;
5 | import myoidc.server.domain.user.UserPrivilege;
6 | import myoidc.server.domain.user.UserRepository;
7 | import myoidc.server.infrastructure.AbstractRepositoryTest;
8 | import org.junit.Test;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 |
11 | import java.util.List;
12 |
13 | import static org.junit.Assert.assertNotNull;
14 | import static org.junit.Assert.assertNull;
15 | import static org.junit.Assert.assertTrue;
16 |
17 | /**
18 | * 2018/3/22
19 | *
20 | * @author Shengzhao Li
21 | */
22 | public class UserRepositoryHibernateTest extends AbstractRepositoryTest {
23 |
24 |
25 | @Autowired
26 | private UserRepository userRepository;
27 |
28 |
29 | @Test
30 | public void findUserPrivileges() throws Exception {
31 |
32 |
33 | User user = new User().username("test").password("owesdds");
34 | userRepository.saveOrUpdate(user);
35 |
36 | UserPrivilege userPrivilege = new UserPrivilege(user, Privilege.USER);
37 | userRepository.saveOrUpdate(userPrivilege);
38 |
39 | // flush();
40 |
41 | final List privileges = userRepository.findUserPrivileges(user.uuid());
42 | assertNotNull(privileges);
43 | // System.out.println(privileges);
44 | }
45 |
46 |
47 | @Test
48 | public void findUsersByUsername() {
49 |
50 | List list = userRepository.findUsersByUsername("us");
51 | assertTrue(list.isEmpty());
52 |
53 | }
54 |
55 |
56 | @Test
57 | public void findUserByUsernameNoArchived() {
58 |
59 | User user = userRepository.findUserByUsernameNoArchived("user");
60 | assertNull(user);
61 |
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/infrastructure/oidc/OIDCUtilsTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.infrastructure.oidc;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * 2020/3/23
9 | *
10 | * @author Shengzhao Li
11 | * @since 1.1.0
12 | */
13 | public class OIDCUtilsTest {
14 |
15 |
16 | @Test
17 | public void isJWT() {
18 |
19 | assertFalse(OIDCUtils.isJWT("aaa"));
20 | assertFalse(OIDCUtils.isJWT("aaa.bb"));
21 | assertFalse(OIDCUtils.isJWT(""));
22 | assertFalse(OIDCUtils.isJWT(null));
23 | assertFalse(OIDCUtils.isJWT("aaa.bb.cc.dd"));
24 |
25 | assertTrue(OIDCUtils.isJWT("aaa.bb.cc"));
26 | assertTrue(OIDCUtils.isJWT("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im15b2lkYy1rZXlpZCJ9.eyJzdWIiOiJtb2JpbGUiLCJhdWQiOlsibXlvaWRjLXJlc291cmNlIl0sInVzZXJfbmFtZSI6Im1vYmlsZSIsInNjb3BlIjpbIm9wZW5pZCIsInJlYWQiXSwiYXRpIjoiZjcyMmM3ZTQtZDZkMC00ZWVmLThmYWYtZThjZGU5ODA5N2Y0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL215b2lkYy1zZXJ2ZXIvIiwiZXhwIjoxNTg3NDUwMzU2LCJpYXQiOjE1ODQ4NTgzNTYsImF1dGhvcml0aWVzIjpbIlJPTEVfTU9CSUxFIiwiUk9MRV9VU0VSIl0sImp0aSI6ImRkMzQ1NjEzLWExYWUtNDk0OS05MjVhLThiOTc4OTMwZGZjMCIsImNsaWVudF9pZCI6InVaeWlyQTNSdkFtN09UVkk2In0.gGz8j52iCk-40OUTFcLUVpH7VpxhiyenaVEZJ3_hu634BkdLjzpJwk3eGZBixPUQXLvuF3HUPgkevcYrAxn21u2QF4p3Qqr1P2ebT8ERwD1Sov2eeWrdGW_pr4KgyFFSZ64hczCCLZYILmwpXFDzV_dBiUQx0h2ttUAKm55NOQ6Ve-uE48XIBdXvjR9cJwy1EJ-BHgf6lp9xbZi0uQ2Mw2SEgV7C1q9e-1VJzBFGLRH1tD3xX1e5i4We_fqFg_gyTmd4sciQpExFWR1DaYsPnxYtYpVJYnfzPL5JLpw7eImnnw8oO7EWZiibORWem626T-WgzFRVd4lFaFaXqU33uA"));
27 |
28 | }
29 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/java/myoidc/server/service/business/ClientRegistrationFormSaverTest.java:
--------------------------------------------------------------------------------
1 | package myoidc.server.service.business;
2 |
3 | import myoidc.server.domain.oauth.OauthClientDetails;
4 | import myoidc.server.infrastructure.oidc.OIDCUseScene;
5 | import myoidc.server.service.dto.ClientRegistrationFormDto;
6 | import org.junit.Test;
7 |
8 | import static org.junit.Assert.*;
9 |
10 | /**
11 | * 2020/4/1
12 | *
13 | * @author Shengzhao Li
14 | * @since 1.1.0
15 | */
16 | public class ClientRegistrationFormSaverTest {
17 |
18 |
19 | @Test
20 | public void createDomain() throws Exception {
21 |
22 | ClientRegistrationFormDto dto = new ClientRegistrationFormDto(OIDCUseScene.WEB);
23 | dto.setAppName("Test");
24 | dto.setWebServerRedirectUri("https://abc.com/back");
25 | ClientRegistrationFormSaver formSaver = new ClientRegistrationFormSaver(dto);
26 |
27 | OauthClientDetails secret = formSaver.createDomain();
28 | assertNotNull(secret);
29 | // System.out.println(secret);
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/myoidc-server/src/test/resources/application-test.properties:
--------------------------------------------------------------------------------
1 | # MyOIDC -Server V-1.1.0
2 | #
3 | spring.application.name=MyOIDC
4 | #
5 | #JDBC
6 | #Connection
7 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
8 | spring.datasource.url=jdbc:mysql://localhost:3306/myoidc_server_test?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
9 | spring.datasource.username=andaily
10 | spring.datasource.password=andaily
11 | #Datasource properties
12 | spring.datasource.type=com.zaxxer.hikari.HikariDataSource
13 | spring.datasource.hikari.maximum-pool-size=20
14 | spring.datasource.hikari.minimum-idle=2
15 | #
16 | # MVC
17 | spring.mvc.ignore-default-model-on-redirect=false
18 | spring.http.encoding.enabled=true
19 | spring.http.encoding.charset=UTF-8
20 | spring.http.encoding.force=true
21 | #
22 | #THYMELEAF (ThymeleafAutoConfiguration)
23 | #
24 | spring.thymeleaf.prefix=/WEB-INF/view/
25 | spring.thymeleaf.suffix=.html
26 | #spring.thymeleaf.mode=HTML5
27 | spring.thymeleaf.encoding=UTF-8
28 | # ;charset= is added
29 | #spring.thymeleaf.content-type=text/html
30 | # set to false for hot refresh
31 | spring.thymeleaf.cache=false
32 | #
33 | # Logging INFO
34 | #
35 | logging.level.root=WARN
36 | #logging.config=classpath:log4j2.xml
37 | #logging.level.org.springframework.transaction.interceptor=TRACE
38 | #
39 | # Security
40 | #
41 | #security.filter-order=8888
42 | #
43 | #Tomcat Server Config
44 | #
45 | server.tomcat.accesslog.enabled=true
46 | server.tomcat.uri-encoding=UTF-8
47 | server.port=8080
48 | #
49 | # gzip, compression
50 | server.compression.enabled=true
51 | server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
52 | server.compression.min-response-size=1024
53 | #
54 | #Application host url, end by '/'
55 | application.host=http://localhost:7777/myoidc-server/
56 |
57 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/resources/jwks_ec.json:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "kty": "EC",
5 | "d": "bFH2NXpNxjEKGrnnjJCLrrBfEIxKw9o4qfBAYzowdCQ",
6 | "use": "sig",
7 | "crv": "P-256",
8 | "kid": "myoidc-keyid",
9 | "x": "_E35xwg2gODQkkpBGnKr2SsXVp9l13HXC-dtzfnMQ_c",
10 | "y": "VXzxPdrF8Uj7gBYbaHBDCfwkvpfJU-EhO8fd9Q0JLo4",
11 | "alg": "ES256"
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/resources/jwks_oct.json:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "kty": "oct",
5 | "use": "enc",
6 | "kid": "myoidc-keyid",
7 | "k": "x5nQay6CzVV7kuPeYA7Y23pVk3eJqYZLGMOp9TiwOiVHDyq1vaJzvVrMNJ4qNQaC5YaNn71jmHu3OZ3f1WK9BfpUPIY8RRc-DvssK7Pyjg8oa-2UI_OwY0yIXeaUSC7qJbpI22qyvATiVC6I7kKv3_FXXWeStayJj1gsiQmofqmLl2nmuqyk60jCIQx8TQYN5Fc4dIvIJkYVrOwYfIImAbwxeNifoF-bXeQqLK1DovtJFLg_uA_-Aeabh4QLXAM2VcLUGO9TDhpq-V8WkqX47TooB_r1IhQv0hsHAwvRC_ahHvNkU8OkXdpWUtnlGmtefd8-PWQkq5M0_d-5Jhvnkg",
8 | "alg": "HS256"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/resources/jwks_rsa.json:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "p": "7rfP7BCnbEvA3d4oVxCBPfDRdUz6XCzcTPqv5jLI6rQUpFoWjT-alK1t57NeU-E_D7YXyWhH8xt5tEsYF3jZXrjrDPF2rrSFb45QyZOPpvsxc_BK66d3RVHoN-t_0ZpZ-eUwrUHyiDplnSy61r1ygbe3Ygn4dFo58mG5key92Rk",
5 | "kty": "RSA",
6 | "q": "5-W4swQFw64wxwDtbu0vpiKXiDn45hH3UyyJWMGIobFlELH4u8bCHvQtRLOaKj2ulA_gb6jLuJDM6u-JNc23pGWVpdtbAQHPQoxZFpswzLsrDDfU074PepBZqWDe0IGwPCjEP4s_cadCHWnMyC0J6cG0sXN9ZsdEDaJs0T_DqcU",
7 | "d": "wYFbEfaAthdlipSk7YqeBJ-qZJJDcvcvwiIYPlSzwR9b4A_zSDShRhxknqLviFB2CxrqD_Y_fLub5bnEU6wQM2CdMsm5RU5uva20b5fyjeWmOuALg-BuFL8ZmQK0j9LVqHzDlz9oMxgVwdYAImRzVVXvrIR9VS8_EZrIXAGzs-uqJMiI8ahrsRcd2wt4VAxH5qQxp3cdjs69SIlGY6P2GiZg8VB4NIJscBEqyNW18OIaCOpCOBnKCJ45wBMzQt_dAkMJxJnda7DJnEyQdpKabamt6S2IHFHuJgGqlz9MpXYDMgLK0y4stBQpF8fofvZeeGghZuhMnGeWIoxyIH4cQQ",
8 | "e": "AQAB",
9 | "use": "sig",
10 | "kid": "myoidc-keyid",
11 | "qi": "tSpNOLVW0WEgsIqn46Qu6KdJff-3hwlUWhuseR7CyHx6KBy8hXV6NDsEXpxlMvuWojNbZZTSfLUE8cs2uYFK0qp9mNbaUz-sADpT143QogCmIaDliILaBFOWDOy-E2WoonAzkxWCoRv9K785YsjsXe7AUIenSFFDx4Vohbrkijg",
12 | "dp": "DfVBexQeNf7X8CElSrH0XKLQHIO7v9f_qaCe2F7v0IlnC5UY7HljmH3rhzi9szngbhK_oU8vpc9ddmVNq1GtpBQ76i3UOrLjenpfzumJ5MGbSqQqPU01dCAt69chSig0SqBUEE1i2QRRHLeY1SWOpHcRifH7TRJZgQqlxxqIn0E",
13 | "alg": "RS256",
14 | "dq": "Hs8badU3-tZyro3F_b3PXdAst7GUCuUKKee526vivjC2T7CFblUqxzgDp6QA8Gm_fvZZCByx7DR4tSHb5eUN5-6DIkTxY0HdSmchEurNYfXf80CbqwIORmdVMjang6YnRubXo-WZKT1igEvlJBcvwPm2SvkgCP6iYPlaYbaKBU0",
15 | "n": "2D4TRgzqRdNnXgJa5HiiT7KuA6trpE7UWGTl9ZAInbf2Jk7ZgjH_Fif6vXbNphhH2U-v3jKL2xESEaR_WN4v0okw8s3B0XdIb6nA3idz_aBQ4VcYfQA6D9wGE6l9NoS1L8qxXaVk32S1UfxTC3crBbBiNazF3zYaYwcWwTYrqKqADlC2CKA4UgcmqFEO90JmP9SejpM_MryGhsebZTHbK7nsd0z9P-yORri0BPvAoZY8Scgda1TKdTtuaQTBTWPHnRfNreLHzllUF37G_ebBo_4-9Bjxj35KuOaf1VtpSXm6DHszj5bqdvubPuzS_NCWLYXtBRx4-oVRhfkHB3SRPQ"
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/myoidc-server/src/test/resources/keystore.jwks:
--------------------------------------------------------------------------------
1 | {
2 | "keys": [
3 | {
4 | "alg": "RS256",
5 | "d": "PvBAngE3kkTnD3yDKo3wCvHJHm20kb9a0FVGLd0s2Y0E_3H2XnZC8-2zPhN6AQTjPhohSDCew20gzm76lyOvMqRiUP2Zpaopa1d2fGvNIQSdM07yKa6EivEYxqPQxa5esoZnexgnb9fom70I8n5OQRNQikwu-az26CsHX2zWMRodzSdN5CXHvb1PV09DmH8azTYwoMElPIqmcTfxiRw2Ov5ucmXXngKRFJgvfUgKd7v4ScBX7sQoQEjWEtt7ta0WvL3Ar5E1RAW4aHxuubZ6AtloxWCf17AAKw03dfP5RDm5TDmgm2B635ecJ7fTvneFmg8W_fdMTPRfBlCGNBp3wQ",
6 | "e": "AQAB",
7 | "n": "qt6yOiI_wCoCVlGO0MySsez0VkSqhPvDl3rfabOslx35mYEO-n4ABfIT5Gn2zN-CeIcOZ5ugAXvIIRWv5H55-tzjFazi5IKkOIMCiz5__MtsdxKCqGlZu2zt-BLpqTOAPiflNPpM3RUAlxKAhnYEqNha6-allPnFQupnW_eTYoyuzuedT7dSp90ry0ZcQDimntXWeaSbrYKCj9Rr9W1jn2uTowUuXaScKXTCjAmJVnsD75JNzQfa8DweklTyWQF-Y5Ky039I0VIu-0CIGhXY48GAFe2EFb8VpNhf07DP63p138RWQ1d3KPEM9mYJVpQC68j3wzDQYSljpLf9by7TGw",
8 | "kty": "RSA",
9 | "kid": "rsa1"
10 | },
11 | {
12 | "kty": "RSA",
13 | "kid": "myoidc-keyid",
14 | "n": "iqMKlSdSeKO9cVN_hjFA_HZ-IcEEnTloUBdPNOx5TpD3DNztyG7XTV3OUE1pMy69M7ngGmNM6w9UJ1lt6IjSvm7hHEIjkhRC4QWlYCdS9twSXXmpUIQ1eAdUFauuftuau-J-9qk-28DIlBpKyrPyjJmX0mqo4CcwjURvhI5RYp853aeNSaeqHA3oR8euKLWj66VOcSdGf9OL71IMEOGmthc9q2ZFk2iSvjNSooG0fgWgeRW9tTHoTyD8xSPY2c65hFRZwwL_kaBKuT8GoKMo3H3W485trmdh1TywJ8Z2L-yxIw91ZjTdVN75UK2E6QyshbrYi1SqUa2CPUJqAq7B6Q",
15 | "e": "AQAB",
16 | "d": "cFWB6q-NDMGobB47M5HPVYHx3AnZYkg09MieXoTKGlYuSFbvuTvO6xp6ZOkEt_tERZh0NQ2HMuQdzTCSdRwAn1uavdn9lo0iT9DSWqIigHJ70xAUmHA4HwTZJiIRZyssKtdxBw7GJywDmrXfKnY6r6B4u3-_TLmUhrMQJXloCp9GA6_PKFwHR08W8LoVREWUt7tYKybShyHzTsRuk9mZJkOmIMiGlABdAg3E_7RYs1ufIkiiCofEllpTcLeK-kiUWS9HGGOuCUrdnMG064llqccVUOmqBUr7YG8eSNHvDz3uI-mDQgESD6O3JEQwcGUIgMwyI4oDOnYTB9I9ZdAOsQ",
17 | "p": "y1lqfZF-JuDCSADDSqet-489TpyIm9yC5RNx2VN4j4t7Sbi2R3FE_Sxh95_XOsi-CvR5f-a76B4u19LCwz_v-7YELgfZUHW4Igiq-X9qZ39MzAYRzAJlTkt9SH9R64qk4rs9QrWf-eNL816tcviD8YWeMD3h2uQZSkYnNNPVliU",
18 | "q": "rohMap15I81HF-M9ksLEcOaXBagSFVZeHT2EliTSMarKe0kd5p1nH7fDd2rO9Rpu7x0IA50Tz0nIfRXsWEnNn91sZTdWrfO_-lWmu8g2n6HE2mhEnNsqVO4007UVsUnZT601dTbvrvcxrW4p6VEI9b9teVWl4NpfsEdqPnjzp3U",
19 | "dp": "a26SFEUJoQCdo-zDQG3WPVEv0phgk_esL9pWC7tNtoi6Wfh8VMJC8H7CQ1DvJN9ph-AhULFWFQvdM6jlvMHKx_EhxC_hX-DRpyltKuNmE8ftityqCl45p2O6jNK3NPnKov7JHrVWD29GcQ1UFam2C6PMLzCCYmKf-d2WWRKRhQE",
20 | "dq": "m2iaQsT9vTdoeojJpwjuymlJSKwjjgRdwUOp79fRopAlxCmTCmpWDRQgZREiP3XOGfSL0kvn-8gDUf5XeTYedp8_idEAydwlsc7arJLWsMXm92Oo1NMCmqWRPIIeUsMjUaM12q2UNwO9pGRXxX12sPxHiqcNEW7hjaHJpN8mdpE",
21 | "qi": "rjLpojc7yHt_yqYrT5M4iG2vM0lU8QDcKEEMlsMeF8g4l-f6J4F5MDCRrZ7EbdFQHP-kq6cv8LdeRpr9Hl7OHTdedeXZ5INpuZc3D_9-9_H61qegkO6VY45nzskw6NTDB4_xRF4ENX63ZU9umIEJi36sLLKOwQIyPa3V_zNFv1o"
22 | }
23 | ]
24 | }
--------------------------------------------------------------------------------
/others/How-To-Use.txt:
--------------------------------------------------------------------------------
1 |
2 | 说明 如何部署, 如何使用 MyOIDC
3 |
4 |
5 | [myoidc-server]
6 |
7 | 1. 在MySQL中创建数据库: myoidc_server
8 | create database if not exists myoidc_server default character set utf8;
9 |
10 | 2.在数据库中执行SQL文件: myoidc-server.ddl, initial-db.ddl (others/database/ 目录)
11 | source myoidc-server.ddl
12 | source initial-db.ddl
13 |
14 | 3.修改 application.properties 中的 数据库连接信息 与 application.host
15 | 4.直接运行 MyOIDCServerApplication.java , 访问的默认端口 8086, 初始账号/密码: admin/MyOIDC-2017
16 | 5. 若使用jar方式启动,则命令为
17 | java -jar myoidc-server-{version}.jar
18 | 若使用自定义的 application.properties 文件,则命名为
19 | java -jar myoidc-server-{version}.jar --spring.config.location=application.properties
20 |
21 |
22 |
23 |
24 | [myoidc-client]
25 |
26 | 1. 修改 application.properties 中的 application.host
27 | 2. 直接运行 MyOIDCClientApplication.java , 访问的默认端口 8087
28 | 3. 若使用jar方式启动,则命令为
29 | java -jar myoidc-client-{version}.jar
30 | 若使用自定义的 application.properties 文件,则命名为
31 | java -jar myoidc-client-{version}.jar --spring.config.location=application.properties
32 |
33 | 注意:启动前最好确保 myoidc-server 已经在运行
34 |
35 |
--------------------------------------------------------------------------------
/others/OpenID Connect Standard for Federation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/others/OpenID Connect Standard for Federation.pdf
--------------------------------------------------------------------------------
/others/database/initial-db.ddl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | --
5 | -- Insert default user: admin/MyOIDC-2017
6 | truncate user_;
7 | INSERT INTO user_ (id, uuid, create_time, archived, version, username, password, phone, email, default_user)
8 | VALUES
9 | (21, 'wR4XwW4UdCbfOWuMCYj8lafxApKZHtgl6uls55Ij2i', now(), 0, 0, 'admin', '$2a$10$K2bdNUA09wrgKOMYGCMWeeyb7V49sZluTolXeNf0J14ArEzfn82Qi', NULL,
10 | 'admin@qc8.me', 1);
11 |
12 | -- unity/MyOIDC-2017
13 | INSERT INTO user_ (id, uuid, create_time, archived, version, username, password, phone, email, default_user)
14 | VALUES
15 | (22, 'fFVLrIx6MgVwXDhKUHE23KR3w0KqOulHjSNyf6rC04', now(), 0, 0, 'unity', '$2a$10$K2bdNUA09wrgKOMYGCMWeeyb7V49sZluTolXeNf0J14ArEzfn82Qi', NULL,
16 | 'unity@qc8.me', 1);
17 |
18 | -- mobile/MyOIDC-2017
19 | INSERT INTO user_ (id, uuid, create_time, archived, version, username, password, phone, email, default_user)
20 | VALUES
21 | (23, 'Ajlt9ZwVyGUvxrJCdKlFA4AataAVKVgH6gxYeCxD6J', now(), 0, 0, 'mobile', '$2a$10$K2bdNUA09wrgKOMYGCMWeeyb7V49sZluTolXeNf0J14ArEzfn82Qi', NULL,
22 | 'mobile@qc8.me', 1);
23 |
24 |
25 |
26 | -- user-privilege
27 | truncate user_privilege;
28 | insert into user_privilege(uuid,create_time,user_id,privilege) values ('HJvLBVf1FuOBfEi782TIfoJOxLIKFKPdCTJGlX5ulo',now(),22,'UNITY');
29 | insert into user_privilege(uuid,create_time,user_id,privilege) values ('YAHsOvr8Z57UKeyiRPDn5IpS8HVZ87gEvlfUy8ynAW',now(),23,'MOBILE');
30 |
31 |
32 |
33 | -- initial oauth client details test data
34 | -- 'unity-client' support browser, js(flash) visit, secret: unity
35 | -- 'mobile-client' only support mobile-device visit, secret: mobile
36 | truncate oauth_client_details;
37 | insert into oauth_client_details
38 | (client_id, resource_ids, client_secret, scope, authorized_grant_types,
39 | web_server_redirect_uri,authorities, access_token_validity,
40 | refresh_token_validity, additional_information, create_time, archived, trusted)
41 | values
42 | ('unity-client','myoidc-resource', '$2a$10$QQTKDdNfj9sPjak6c8oWaumvTsa10MxOBOV6BW3DvLWU6VrjDfDam', 'read,openid','authorization_code,refresh_token,implicit',
43 | 'http://localhost:8080/myoidc-server/unity/dashboard','ROLE_CLIENT',null,
44 | null,null, now(), 0, 0),
45 | ('mobile-client','myoidc-resource', '$2a$10$uLvpxfvm3CuUyjIvYq7a9OUmd9b3tHFKrUaMyU/jC01thrTdkBDVm', 'read,openid','password,refresh_token',
46 | null,'ROLE_CLIENT',null,
47 | null,null, now(), 0, 0);
48 |
49 |
--------------------------------------------------------------------------------
/others/development-log.txt:
--------------------------------------------------------------------------------
1 |
2 | 记录开发的点点滴滴!
3 |
4 |
5 |
6 | 2020-03-14
7 | 1. keys 按要求来实现, 增加 use --ok
8 | 2. 生成的token中增加 kid, -- ok
9 | 3.openid scope时要有 access_token, id_token -- ok
10 | 4. 去掉 jpa, 用 hibernate --ok
11 |
12 |
13 | 2020-03-18
14 | 1.初始密码修改至少10位 ok
15 | 2.完成客户端RP管理 ok
16 | 3.完成用户EU管理 ok
17 | 4.API提供基础实现 ok
18 |
19 |
20 |
21 | 2020-03-19
22 | 1.API完善并进行各API具体的测试 --ok
23 | 2.考虑把 access_token不使用 id_token 格式 --取消
24 | 3. myoidc-client 准备设计与实现
25 | 4.升级 spring security oauth2, jwt 版本并测试 -- 保持不变
26 | 5.db_table_description.html检查内容 --ok
27 |
28 |
29 |
30 | 2020-03-22
31 | 1.用户EU增加 archive 功能(默认用户不能archived) ok
32 |
33 |
34 | 2020-03-25
35 | 1.注册客户端API实现
36 |
37 |
--------------------------------------------------------------------------------
/others/images/Security-Token-Service.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/others/images/Security-Token-Service.png
--------------------------------------------------------------------------------
/others/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/others/images/favicon.ico
--------------------------------------------------------------------------------
/others/images/openid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/others/images/openid.png
--------------------------------------------------------------------------------
/others/key/private_key.json:
--------------------------------------------------------------------------------
1 | {
2 | "kty": "RSA",
3 | "kid": "myoidc-keyid",
4 | "use": "sig",
5 | "alg": "RS256",
6 | "n": "n6X4_VZSQjxmSqBqmIq5ZbaLynXPP3yCOF2xE250NaYLferU8LX3xAvuNLnZkaUH-4cnr_JuSlN_7JIAwAd5oLHSuSByPcxSJ95uGniDji22s-yQ19rqZCQHLmJwg3WZpWPN-HmwxPOFNlkW_2ETjqMzS-3kGduz-IPfebwNbVFu6RglHT_V6IyaDUbSvV80AAQ7R8Y6xBvu25ZSniu3JHj2u8AtScJgiOqfsImsaCABdmUO4LtMzB1V7pafH-_puRWYCl5_uaYYPMxv-EOonPCyTlzJtC6ZeiiI4LNtxWwEamRyTS0xX8Czt3s5mRW2q6pgMZQsqlL64Df8MDuFpQ",
7 | "e": "AQAB",
8 | "d": "E92YRRXnuHxBkkmx2fdxKHn1nSTZvCGnJpJqBWv6I-7cgTemdal_AjMl2gPCUgBCJQdlZdx54t_PDEYCt-J2PQvDl-u0q4HwOyvPcZXLcPa5RFxMjb-c6QceqaPwMjuA-faYW7Hw0CEpU2D0nqSaxWYDbRBWEO2o0GTAeypuVUrZXGilOLjal68Tho8ZYbmyXsEvEdqCob_iUe6q4c2x0amMmn2ot3bKKqdjbVXMjVfEqHHMPMdnVmrr_yfTUlXN3ZT4Ypp7wDrAVs7pfbvrCKWzLQYlbYNjZeBoKNcGabAA7WuNGxWvi3971gLSdYwRw4TngOweIhVW8kxiiA77QQ",
9 | "p": "2R_SdLqd7d7hVJTAVY4Twx8j7VQq6-TTMVcyD_YLeBGvlkngpSz7NSQu1LTYGEHa_CzeCOFmKgtuLZ84zyS_wUxgF3AH0VD-xNZSAaHfzWXAwLmezYzGBXXF0ho8qpbf2aTNZZx2n5z0cb0loitAfmfrsd9XU226nXpPAgV-gTE",
10 | "q": "vDup5zcW9NwxVs9-C-W1uwL7TpQIKNk9oBvbfgD6XkwIn3JmCfny2Nm-paK45YM169JhnUml7z6On2Bq81rNtPwkqWTp9d2SfsQkuNddtfeYi_FulLqMLeQvCr2TAdFE-4uYKcU_-5u21oomnVm5vgGs8aFzd_J-57i-GfPxjrU",
11 | "dp": "UwpZqm1JQ5WvpnKx0MbjBghd7EH5nHjK0R8hNXuLzWMuPZOJyIKYnS12f8GeuEBPqYzbapgSQ9hVTjuMNaU_dYVpZu1hAAwzNEMn4BnyB5N4Ef2sH79MaQAvJXkFZNUJTis6pzcdI1SbJPkLcKeMJgxG16OsuWrJKbuChiplxLE",
12 | "dq": "aQYJGD6-ikRJKxx-QXkbWoqhWQhzPQdowOqKHtXA29gkf4I-uJZDDwb-vj_6VeRNs5Qgbrfm44PN49LSGZGycKa2deUePNYxpJUfwBo56QuKi5pbjpQ_HmPQc3eujDcM_CS486Vgu6v36eAPB4BGiGM68V6ZpHUipXuIZcacInk",
13 | "qi": "bvay2Ej4FIYrFpD0zW-xEpHoPxXmNJRyR4rL4SGVq-ILghfVqfTQszI2MUnpubcUAUsqYYZUvvemfust35eYiSaYWzUDGsjmUWhZDD8VTKEyxbWwya7GztarLMud2LGn76a41zyStU46g84G1ZPNcZTK_1DIR0_BpayN44jj3kk"
14 | }
--------------------------------------------------------------------------------
/others/key/public_key.json:
--------------------------------------------------------------------------------
1 | {
2 | "kty": "RSA",
3 | "kid": "myoidc-keyid",
4 | "use": "sig",
5 | "alg": "RS256",
6 | "n": "n6X4_VZSQjxmSqBqmIq5ZbaLynXPP3yCOF2xE250NaYLferU8LX3xAvuNLnZkaUH-4cnr_JuSlN_7JIAwAd5oLHSuSByPcxSJ95uGniDji22s-yQ19rqZCQHLmJwg3WZpWPN-HmwxPOFNlkW_2ETjqMzS-3kGduz-IPfebwNbVFu6RglHT_V6IyaDUbSvV80AAQ7R8Y6xBvu25ZSniu3JHj2u8AtScJgiOqfsImsaCABdmUO4LtMzB1V7pafH-_puRWYCl5_uaYYPMxv-EOonPCyTlzJtC6ZeiiI4LNtxWwEamRyTS0xX8Czt3s5mRW2q6pgMZQsqlL64Df8MDuFpQ",
7 | "e": "AQAB"
8 | }
--------------------------------------------------------------------------------
/others/springboot/myoidc.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/others/springboot/myoidc.zip
--------------------------------------------------------------------------------
/others/springboot/spring-boot-reference(2.0.0).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkeyk/MyOIDC/e477f9651bb00bc3adf7787ce64907a281b7e871/others/springboot/spring-boot-reference(2.0.0).pdf
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | myoidc
8 | MyOIDC
9 | 1.1.1
10 | ${project.artifactId}
11 | pom
12 | OpenID Connect Implements
13 |
14 |
15 | UTF-8
16 |
17 |
18 |
19 |
20 | myoidc-server
21 | myoidc-client
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | org.apache.maven.plugins
30 | maven-compiler-plugin
31 | 2.3.2
32 |
33 | utf-8
34 | 1.8
35 | 1.8
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------