diff --git a/README.md b/README.md index feed056..b432a11 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Base on Spring-Boot
  1. JDK (1.8.0_40)
  2. Servlet (3.1.0)
  3. -
  4. Spring Boot(1.5.9.RELEASE)
  5. +
  6. Spring Boot(2.0.1.RELEASE)

diff --git a/others/database/initial_data.ddl b/others/database/initial_data.ddl index d6e6d22..1bbed0a 100644 --- a/others/database/initial_data.ddl +++ b/others/database/initial_data.ddl @@ -5,35 +5,35 @@ truncate user_privilege; -- admin, password is admin ( All privileges) insert into user_(id,guid,create_time,email,password,phone,username,default_user) values -(21,'29f6004fb1b0466f9572b02bf2ac1be8',now(),'admin@wdcy.cc','21232f297a57a5a743894a0e4a801fc3','028-1234567','admin',true); +(21,'29f6004fb1b0466f9572b02bf2ac1be8',now(),'admin@andaily.com','$2a$10$XWN7zOvSLDiyxQnX01KMXuf5NTkkuAUtt23YxUMWaIPURcR7bdULi','028-1234567','admin',true); -- unity, password is unity ( ROLE_UNITY) insert into user_(id,guid,create_time,email,password,phone,username,default_user) values -(22,'55b713df1c6f423e842ad68668523c49',now(),'unity@wdcy.cc','439b3a25b555b3bc8667a09a036ae70c','','unity',false); +(22,'55b713df1c6f423e842ad68668523c49',now(),'unity@andaily.com','$2a$10$gq3eUch/h.eHt20LpboSXeeZinzSLBk49K5KD.Ms4/1tOAJIsrrfq','','unity',false); insert into user_privilege(user_id,privilege) values (22,'UNITY'); -- mobile, password is mobile ( ROLE_MOBILE) insert into user_(id,guid,create_time,email,password,phone,username,default_user) values -(23,'612025cb3f964a64a48bbdf77e53c2c1',now(),'mobile@wdcy.cc','532c28d5412dd75bf975fb951c740a30','','mobile',false); +(23,'612025cb3f964a64a48bbdf77e53c2c1',now(),'mobile@andaily.com','$2a$10$BOmMzLDaoiIQ4Q1pCw6Z4u0gzL01B8bNL.0WUecJ2YxTtHVRIA8Zm','','mobile',false); insert into user_privilege(user_id,privilege) values (23,'MOBILE'); -- initial oauth client details test data --- 'unity-client' support browser, js(flash) visit --- 'mobile-client' only support mobile-device visit +-- 'unity-client' support browser, js(flash) visit, secret: unity +-- 'mobile-client' only support mobile-device visit, secret: mobile truncate oauth_client_details; insert into oauth_client_details (client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri,authorities, access_token_validity, refresh_token_validity, additional_information, create_time, archived, trusted) values -('unity-client','unity-resource', 'unity', 'read,write','authorization_code,refresh_token,implicit', -null,'ROLE_CLIENT',null, +('unity-client','unity-resource', '$2a$10$QQTKDdNfj9sPjak6c8oWaumvTsa10MxOBOV6BW3DvLWU6VrjDfDam', 'read,write','authorization_code,refresh_token,implicit', +'http://localhost:8080/spring-oauth-server/unity/dashboard','ROLE_CLIENT',null, null,null, now(), 0, 0), -('mobile-client','mobile-resource', 'mobile', 'read,write','password,refresh_token', +('mobile-client','mobile-resource', '$2a$10$uLvpxfvm3CuUyjIvYq7a9OUmd9b3tHFKrUaMyU/jC01thrTdkBDVm', 'read,write','password,refresh_token', null,'ROLE_CLIENT',null, null,null, now(), 0, 0); diff --git a/others/database/initial_db.ddl b/others/database/initial_db.ddl index e916f8f..a488364 100644 --- a/others/database/initial_db.ddl +++ b/others/database/initial_db.ddl @@ -1,8 +1,8 @@ -- ############### -- create MySQL database , if need create, cancel the comment -- ############### --- create database if not exists oauth2 default character set utf8; --- use oauth2 set default character = utf8; +-- create database if not exists oauth2_boot default character set utf8; +-- use oauth2_boot set default character = utf8; -- ############### -- grant privileges to oauth2/oauth2 diff --git a/pom.xml b/pom.xml index ce19833..938c442 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 1.5.9.RELEASE + 2.0.1.RELEASE @@ -23,6 +23,7 @@ UTF-8 1.8 + 2.3.0.RELEASE false @@ -44,14 +45,7 @@ org.springframework.boot spring-boot-starter-security - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.thymeleaf.extras - thymeleaf-extras-springsecurity4 - + org.springframework.boot spring-boot-starter-validation @@ -65,10 +59,36 @@ spring-boot-starter-jdbc - + org.springframework.security.oauth spring-security-oauth2 + ${spring.security.oauth.version} + + + + + org.springframework.security + spring-security-taglibs + 4.2.3.RELEASE + + + org.springframework.security + spring-security-acl + + + org.springframework + spring-beans + + + org.springframework + spring-core + + + org.springframework + spring-expression + + @@ -84,6 +104,19 @@ 2.6 + + + org.sitemesh + sitemesh + 3.0.1 + + + + javax.servlet + jstl + + + org.springframework.boot diff --git a/src/main/java/com/monkeyk/sos/SpringOauthServerServletInitializer.java b/src/main/java/com/monkeyk/sos/SpringOauthServerServletInitializer.java index c97cd69..be871eb 100644 --- a/src/main/java/com/monkeyk/sos/SpringOauthServerServletInitializer.java +++ b/src/main/java/com/monkeyk/sos/SpringOauthServerServletInitializer.java @@ -2,7 +2,7 @@ package com.monkeyk.sos; import com.monkeyk.sos.web.WebUtils; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -18,8 +18,8 @@ public class SpringOauthServerServletInitializer extends SpringBootServletInitia @Override public void onStartup(ServletContext servletContext) throws ServletException { super.onStartup(servletContext); - - servletContext.setAttribute("sosVersion", WebUtils.VERSION); + //主版本号 + servletContext.setAttribute("mainVersion", WebUtils.VERSION); } diff --git a/src/main/java/com/monkeyk/sos/config/MVCConfiguration.java b/src/main/java/com/monkeyk/sos/config/MVCConfiguration.java new file mode 100644 index 0000000..2d61338 --- /dev/null +++ b/src/main/java/com/monkeyk/sos/config/MVCConfiguration.java @@ -0,0 +1,82 @@ +package com.monkeyk.sos.config; + + +import com.monkeyk.sos.web.filter.CharacterEncodingIPFilter; +import com.monkeyk.sos.web.filter.SOSSiteMeshFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.servlet.Filter; +import java.nio.charset.Charset; +import java.util.List; + +/** + * 2018/1/30 + *

+ * Spring MVC 扩展配置 + *

+ * + * @author Shengzhao Li + */ +@Configuration +public class MVCConfiguration implements WebMvcConfigurer { + + + /** + * 扩展拦截器 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + + WebMvcConfigurer.super.addInterceptors(registry); + } + + + /** + * 解决乱码问题 + * For UTF-8 + */ + @Override + public void configureMessageConverters(List> converters) { + WebMvcConfigurer.super.configureMessageConverters(converters); + converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8"))); + } + + + + + /** + * 字符编码配置 UTF-8 + */ + @Bean + public FilterRegistrationBean encodingFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new CharacterEncodingIPFilter()); + registrationBean.addUrlPatterns("/*"); + //值越小越靠前 + registrationBean.setOrder(1); + return registrationBean; + } + + + /** + * sitemesh filter + */ + @Bean + public FilterRegistrationBean sitemesh() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new SOSSiteMeshFilter()); + registrationBean.addUrlPatterns("/*"); + //注意: 在 spring security filter之后 + registrationBean.setOrder(8899); + return registrationBean; + } + + + +} diff --git a/src/main/java/com/monkeyk/sos/config/OAuth2MethodSecurityConfiguration.java b/src/main/java/com/monkeyk/sos/config/OAuth2MethodSecurityConfiguration.java new file mode 100644 index 0000000..70f5bd6 --- /dev/null +++ b/src/main/java/com/monkeyk/sos/config/OAuth2MethodSecurityConfiguration.java @@ -0,0 +1,24 @@ +package com.monkeyk.sos.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; +import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler; + +/** + * 2018/3/22 + * + * @author Shengzhao Li + */ +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) +public class OAuth2MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { + + + @Override + protected MethodSecurityExpressionHandler createExpressionHandler() { + return new OAuth2MethodSecurityExpressionHandler(); + } + +} diff --git a/src/main/java/com/monkeyk/sos/config/OAuth2ServerConfig.java b/src/main/java/com/monkeyk/sos/config/OAuth2ServerConfig.java deleted file mode 100644 index 77d7cb9..0000000 --- a/src/main/java/com/monkeyk/sos/config/OAuth2ServerConfig.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.monkeyk.sos.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.AccessDecisionManager; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; -import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; -import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; -import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; -import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; -import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; -import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; -import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; -import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; -import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; -import org.springframework.security.oauth2.provider.token.TokenStore; - -/** - * 2016/4/4 - * - * @author Shengzhao Li - */ -@Configuration -public class OAuth2ServerConfig { - - private static final String UNITY_RESOURCE_ID = "unity-resource"; - private static final String MOBILE_RESOURCE_ID = "mobile-resource"; - - // unity-resource - @Configuration - @EnableResourceServer - protected static class UnityResourceServerConfiguration extends ResourceServerConfigurerAdapter { - - - @Autowired - private AccessDecisionManager oauth2AccessDecisionManager; - - @Override - public void configure(ResourceServerSecurityConfigurer resources) { - resources.resourceId(UNITY_RESOURCE_ID).stateless(false); - } - - @Override - public void configure(HttpSecurity http) throws Exception { - - http.sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) - .and() - .requestMatchers().antMatchers("/unity/**") - .and() - .authorizeRequests() - .antMatchers("/unity/**") - .access("#oauth2.hasScope('read') or (!#oauth2.isOAuth() and hasRole('ROLE_UNITY'))"); -// .accessDecisionManager(oauth2AccessDecisionManager) -// .and().csrf().disable(); - - } - - } - - - //AuthorizationServer - @Configuration - @EnableAuthorizationServer - protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { - -// @Autowired -// private DefaultTokenServices tokenServices; - - @Autowired - private TokenStore tokenStore; - - @Autowired - private UserApprovalHandler userApprovalHandler; - - @Autowired - private AuthorizationCodeServices authorizationCodeServices; -// @Autowired -// private ClientDetailsService clientDetailsService; -// @Autowired -// private OAuth2AccessDeniedHandler oauth2AccessDeniedHandler; -// @Autowired -// private OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint; - - @Override - public void configure(ClientDetailsServiceConfigurer clients) throws Exception { -// clients.withClientDetails(clientDetailsService); - clients.inMemory().withClient("unity-client") - .resourceIds(UNITY_RESOURCE_ID) - .authorizedGrantTypes("authorization_code", "refresh_token", "implicit") - .authorities("ROLE_UNITY") - .scopes("read") - .secret("unity") - .and() - .withClient("mobile-client") - .resourceIds(MOBILE_RESOURCE_ID) - .authorizedGrantTypes("password", "refresh_token") - .authorities("ROLE_CLIENT") - .scopes("read") - .secret("mobile"); - } - - - @Override - public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { - endpoints.tokenStore(tokenStore) - .userApprovalHandler(userApprovalHandler) - .authorizationCodeServices(authorizationCodeServices); - } - - @Override - public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { -// security.accessDeniedHandler(oauth2AccessDeniedHandler) -// .authenticationEntryPoint(oAuth2AuthenticationEntryPoint) -// .allowFormAuthenticationForClients(); - security.realm("spring-oauth-server_realm"); - } - - - } - - -} diff --git a/src/main/java/com/monkeyk/sos/config/OAuth2ServerConfiguration.java b/src/main/java/com/monkeyk/sos/config/OAuth2ServerConfiguration.java new file mode 100644 index 0000000..d7f576a --- /dev/null +++ b/src/main/java/com/monkeyk/sos/config/OAuth2ServerConfiguration.java @@ -0,0 +1,186 @@ +package com.monkeyk.sos.config; + + +import com.monkeyk.sos.domain.oauth.CustomJdbcClientDetailsService; +import com.monkeyk.sos.service.OauthService; +import com.monkeyk.sos.service.UserService; +import com.monkeyk.sos.web.oauth.OauthUserApprovalHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.OAuth2RequestFactory; +import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; +import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; +import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices; +import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; + +import javax.sql.DataSource; + +/** + * 2018/2/8 + *

+ *

+ * OAuth2 config + * + * @author Shengzhao Li + */ +@Configuration +public class OAuth2ServerConfiguration { + + + // unity resource + @Configuration + @EnableResourceServer + protected static class UnityResourceServerConfiguration extends ResourceServerConfigurerAdapter { + + @Override + public void configure(ResourceServerSecurityConfigurer resources) { + resources.resourceId("unity-resource").stateless(false); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http + // Since we want the protected resources to be accessible in the UI as well we need + // session creation to be allowed (it's disabled by default in 2.0.6) + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) + .and() + .requestMatchers().antMatchers("/unity/**") + .and() + .authorizeRequests() + .antMatchers("/unity/**").access("#oauth2.hasScope('read') and hasRole('ROLE_UNITY')"); + + } + + } + + // mobile resource + @Configuration + @EnableResourceServer + protected static class MobileResourceServerConfiguration extends ResourceServerConfigurerAdapter { + + @Override + public void configure(ResourceServerSecurityConfigurer resources) { + resources.resourceId("mobile-resource").stateless(false); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http + // Since we want the protected resources to be accessible in the UI as well we need + // session creation to be allowed (it's disabled by default in 2.0.6) + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) + .and() + .requestMatchers().antMatchers("/m/**") + .and() + .authorizeRequests() + .antMatchers("/m/**").access("#oauth2.hasScope('read') and hasRole('ROLE_MOBILE')"); + + } + + } + + @Configuration + @EnableAuthorizationServer + protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { + + + @Autowired + private TokenStore tokenStore; + + + @Autowired + private ClientDetailsService clientDetailsService; + + + @Autowired + private OauthService oauthService; + + + @Autowired + private AuthorizationCodeServices authorizationCodeServices; + + + @Autowired + private UserService userDetailsService; + + + @Autowired + @Qualifier("authenticationManagerBean") + private AuthenticationManager authenticationManager; + + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + + clients.withClientDetails(clientDetailsService); + } + + + @Bean + public TokenStore tokenStore(DataSource dataSource) { + return new JdbcTokenStore(dataSource); + } + + + @Bean + public ClientDetailsService clientDetailsService(DataSource dataSource) { + return new CustomJdbcClientDetailsService(dataSource); + } + + + @Bean + public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource) { + return new JdbcAuthorizationCodeServices(dataSource); + } + + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.tokenStore(tokenStore) + .authorizationCodeServices(authorizationCodeServices) + .userApprovalHandler(userApprovalHandler()) + .authenticationManager(authenticationManager); + } + + @Override + public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.realm("spring-oauth-server") + .allowFormAuthenticationForClients(); + } + + @Bean + public OAuth2RequestFactory oAuth2RequestFactory() { + return new DefaultOAuth2RequestFactory(clientDetailsService); + } + + + @Bean + public UserApprovalHandler userApprovalHandler() { + OauthUserApprovalHandler userApprovalHandler = new OauthUserApprovalHandler(); + userApprovalHandler.setOauthService(oauthService); + userApprovalHandler.setTokenStore(tokenStore); + userApprovalHandler.setClientDetailsService(this.clientDetailsService); + userApprovalHandler.setRequestFactory(oAuth2RequestFactory()); + return userApprovalHandler; + } + + } + + +} diff --git a/src/main/java/com/monkeyk/sos/config/WebSecurityConfigurer.java b/src/main/java/com/monkeyk/sos/config/WebSecurityConfigurer.java index 8c40c7c..adf11bc 100644 --- a/src/main/java/com/monkeyk/sos/config/WebSecurityConfigurer.java +++ b/src/main/java/com/monkeyk/sos/config/WebSecurityConfigurer.java @@ -1,40 +1,21 @@ package com.monkeyk.sos.config; -import com.monkeyk.sos.domain.oauth.CustomJdbcClientDetailsService; -import com.monkeyk.sos.service.OauthService; import com.monkeyk.sos.service.UserService; -import com.monkeyk.sos.web.oauth.OauthUserApprovalHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.vote.AuthenticatedVoter; -import org.springframework.security.access.vote.RoleVoter; -import org.springframework.security.access.vote.UnanimousBased; +import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.encoding.Md5PasswordEncoder; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.oauth2.provider.ClientDetailsService; -import org.springframework.security.oauth2.provider.OAuth2RequestFactory; -import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; -import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService; -import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; -import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices; -import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; -import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; -import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; -import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; -import org.springframework.security.oauth2.provider.token.TokenStore; -import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; -import org.springframework.security.oauth2.provider.vote.ScopeVoter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import javax.sql.DataSource; -import java.util.Arrays; - /** * 2016/4/3 *

@@ -51,145 +32,72 @@ public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { private UserService userService; - @Autowired - public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userService); -// auth.inMemoryAuthentication().withUser("marissa").password("koala").roles("USER").and().withUser("paul") -// .password("emu").roles("USER"); + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); } - @Override public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - web.expressionHandler(new OAuth2WebSecurityExpressionHandler()); + //Ignore, public + web.ignoring().antMatchers("/public/**", "/static/**"); } - - @Override protected void configure(HttpSecurity http) throws Exception { - +// http.csrf().disable() http.authorizeRequests() - .antMatchers("/oauth/**").hasAnyRole("ROLE_USER", "ROLE_UNITY", "ROLE_MOBILE") -// .antMatchers("/**").anonymous() + .antMatchers("/public/**").permitAll() + .antMatchers("/resources/**").permitAll() + .antMatchers("/login*").permitAll() + + .antMatchers("/admin/**").hasAnyRole("ADMIN") + + .antMatchers(HttpMethod.GET, "/login*").anonymous() + .anyRequest().authenticated() .and() - .exceptionHandling().accessDeniedPage("/login.jsp?authorization_error=2") + .formLogin() + .loginPage("/login") + .loginProcessingUrl("/signin") + .failureUrl("/login?error=1") + .usernameParameter("oidc_user") + .passwordParameter("oidcPwd") .and() .csrf() .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")) + .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")) .disable() .logout() - .logoutUrl("/logout.do") - .logoutSuccessUrl("/index.jsp") + .logoutUrl("/signout") + .deleteCookies("JSESSIONID") + .logoutSuccessUrl("/") .and() - .formLogin() - .loginProcessingUrl("/login.do") - .failureUrl("/login.jsp?authentication_error=1") - .loginPage("/login.jsp") - .defaultSuccessUrl("/index.jsp"); - + .exceptionHandling(); + http.authenticationProvider(authenticationProvider()); } - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userService) - .passwordEncoder(new Md5PasswordEncoder()); - } - - /* - * OAuth2 Configuration start - * */ - - @Bean(name = "clientDetailsService") - public ClientDetailsService clientDetailsService(DataSource dataSource) { - return new CustomJdbcClientDetailsService(dataSource); + @Bean + public AuthenticationProvider authenticationProvider() { + DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); + daoAuthenticationProvider.setUserDetailsService(userService); + daoAuthenticationProvider.setPasswordEncoder(passwordEncoder()); + return daoAuthenticationProvider; } - @Bean(name = "tokenStore") - public TokenStore tokenStore(DataSource dataSource) { - return new JdbcTokenStore(dataSource); + /** + * BCrypt 加密 + * + * @return PasswordEncoder + */ + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); } -// @Bean(name = "tokenServices") -// public DefaultTokenServices tokenServices(TokenStore tokenStore, ClientDetailsService clientDetailsService) { -// final DefaultTokenServices tokenServices = new DefaultTokenServices(); -// tokenServices.setTokenStore(tokenStore); -// tokenServices.setClientDetailsService(clientDetailsService); -// tokenServices.setSupportRefreshToken(true); -// return tokenServices; -// } - - @Bean(name = "oAuth2RequestFactory") - public OAuth2RequestFactory oAuth2RequestFactory(ClientDetailsService clientDetailsService) { - return new DefaultOAuth2RequestFactory(clientDetailsService); - } - - - @Bean(name = "oauthUserApprovalHandler") - public UserApprovalHandler oauthUserApprovalHandler(TokenStore tokenStore, ClientDetailsService clientDetailsService, OAuth2RequestFactory oAuth2RequestFactory, OauthService oauthService) { - OauthUserApprovalHandler userApprovalHandler = new OauthUserApprovalHandler(); - userApprovalHandler.setTokenStore(tokenStore); - userApprovalHandler.setClientDetailsService(clientDetailsService); - userApprovalHandler.setRequestFactory(oAuth2RequestFactory); - userApprovalHandler.setOauthService(oauthService); - return userApprovalHandler; - } - - - @Bean(name = "jdbcAuthorizationCodeServices") - public AuthorizationCodeServices jdbcAuthorizationCodeServices(DataSource dataSource) { - return new JdbcAuthorizationCodeServices(dataSource); - } - - - @Bean(name = "oauth2AuthenticationEntryPoint") - public OAuth2AuthenticationEntryPoint oauth2AuthenticationEntryPoint() { - return new OAuth2AuthenticationEntryPoint(); - } - - - @Bean(name = "oauth2ClientDetailsUserService") - public ClientDetailsUserDetailsService oauth2ClientDetailsUserService(ClientDetailsService clientDetailsService) { - return new ClientDetailsUserDetailsService(clientDetailsService); - } - - -// @Bean(name = "oauth2AuthenticationManager") -// public AuthenticationManager oauth2AuthenticationManager(ClientDetailsUserDetailsService detailsService) { -// DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); -// daoAuthenticationProvider.setUserDetailsService(detailsService); -// List providers = Arrays.asList(daoAuthenticationProvider); -// return new ProviderManager(providers); -// } - - - @Bean(name = "oauth2AccessDecisionManager") - public UnanimousBased oauth2AccessDecisionManager() { - return new UnanimousBased(Arrays.asList( - new ScopeVoter(), - new RoleVoter(), - new AuthenticatedVoter())); - } - - - @Bean(name = "oauth2AccessDeniedHandler") - public OAuth2AccessDeniedHandler oauth2AccessDeniedHandler() { - return new OAuth2AccessDeniedHandler(); - } - - -// @Bean(name = "clientCredentialsTokenEndpointFilter") -// public ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter(AuthenticationManager oauth2AuthenticationManager) { -// ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter = new ClientCredentialsTokenEndpointFilter(); -// clientCredentialsTokenEndpointFilter.setAuthenticationManager(oauth2AuthenticationManager); -// return clientCredentialsTokenEndpointFilter; -// } - - } diff --git a/src/main/java/com/monkeyk/sos/infrastructure/PasswordHandler.java b/src/main/java/com/monkeyk/sos/infrastructure/PasswordHandler.java index b1a8d88..85f36ab 100644 --- a/src/main/java/com/monkeyk/sos/infrastructure/PasswordHandler.java +++ b/src/main/java/com/monkeyk/sos/infrastructure/PasswordHandler.java @@ -1,6 +1,6 @@ package com.monkeyk.sos.infrastructure; -import org.springframework.security.authentication.encoding.Md5PasswordEncoder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** * 2016/3/25 @@ -14,8 +14,8 @@ public abstract class PasswordHandler { } - public static String md5(String password) { - Md5PasswordEncoder encoder = new Md5PasswordEncoder(); - return encoder.encodePassword(password, null); + public static String encode(String password) { + BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + return encoder.encode(password); } } diff --git a/src/main/java/com/monkeyk/sos/service/OauthService.java b/src/main/java/com/monkeyk/sos/service/OauthService.java index 37fcb7d..2730fe9 100644 --- a/src/main/java/com/monkeyk/sos/service/OauthService.java +++ b/src/main/java/com/monkeyk/sos/service/OauthService.java @@ -1,6 +1,6 @@ package com.monkeyk.sos.service; -import com.monkeyk.sos.domain.dto.OauthClientDetailsDto; +import com.monkeyk.sos.service.dto.OauthClientDetailsDto; import com.monkeyk.sos.domain.oauth.OauthClientDetails; import java.util.List; diff --git a/src/main/java/com/monkeyk/sos/service/UserService.java b/src/main/java/com/monkeyk/sos/service/UserService.java index 51250e7..c3ae7be 100644 --- a/src/main/java/com/monkeyk/sos/service/UserService.java +++ b/src/main/java/com/monkeyk/sos/service/UserService.java @@ -1,8 +1,8 @@ package com.monkeyk.sos.service; -import com.monkeyk.sos.domain.dto.UserFormDto; -import com.monkeyk.sos.domain.dto.UserJsonDto; -import com.monkeyk.sos.domain.dto.UserOverviewDto; +import com.monkeyk.sos.service.dto.UserFormDto; +import com.monkeyk.sos.service.dto.UserJsonDto; +import com.monkeyk.sos.service.dto.UserOverviewDto; import org.springframework.security.core.userdetails.UserDetailsService; /** diff --git a/src/main/java/com/monkeyk/sos/domain/dto/OauthClientDetailsDto.java b/src/main/java/com/monkeyk/sos/service/dto/OauthClientDetailsDto.java similarity index 99% rename from src/main/java/com/monkeyk/sos/domain/dto/OauthClientDetailsDto.java rename to src/main/java/com/monkeyk/sos/service/dto/OauthClientDetailsDto.java index 137c0bd..7a3839b 100644 --- a/src/main/java/com/monkeyk/sos/domain/dto/OauthClientDetailsDto.java +++ b/src/main/java/com/monkeyk/sos/service/dto/OauthClientDetailsDto.java @@ -1,4 +1,4 @@ -package com.monkeyk.sos.domain.dto; +package com.monkeyk.sos.service.dto; import com.monkeyk.sos.domain.oauth.OauthClientDetails; import com.monkeyk.sos.infrastructure.DateUtils; diff --git a/src/main/java/com/monkeyk/sos/domain/dto/UserDto.java b/src/main/java/com/monkeyk/sos/service/dto/UserDto.java similarity index 98% rename from src/main/java/com/monkeyk/sos/domain/dto/UserDto.java rename to src/main/java/com/monkeyk/sos/service/dto/UserDto.java index 7ae5b19..b0eebd3 100644 --- a/src/main/java/com/monkeyk/sos/domain/dto/UserDto.java +++ b/src/main/java/com/monkeyk/sos/service/dto/UserDto.java @@ -9,7 +9,7 @@ * it only in accordance with the terms of the license agreement you * entered into with MONKEYK Information Technology Co. Ltd. */ -package com.monkeyk.sos.domain.dto; +package com.monkeyk.sos.service.dto; import com.monkeyk.sos.domain.user.Privilege; import com.monkeyk.sos.domain.user.User; diff --git a/src/main/java/com/monkeyk/sos/domain/dto/UserFormDto.java b/src/main/java/com/monkeyk/sos/service/dto/UserFormDto.java similarity index 89% rename from src/main/java/com/monkeyk/sos/domain/dto/UserFormDto.java rename to src/main/java/com/monkeyk/sos/service/dto/UserFormDto.java index 1fd4928..1468c16 100644 --- a/src/main/java/com/monkeyk/sos/domain/dto/UserFormDto.java +++ b/src/main/java/com/monkeyk/sos/service/dto/UserFormDto.java @@ -1,4 +1,4 @@ -package com.monkeyk.sos.domain.dto; +package com.monkeyk.sos.service.dto; import com.monkeyk.sos.domain.user.Privilege; import com.monkeyk.sos.domain.user.User; @@ -36,7 +36,7 @@ public class UserFormDto extends UserDto { .username(getUsername()) .phone(getPhone()) .email(getEmail()) - .password(PasswordHandler.md5(getPassword())); + .password(PasswordHandler.encode(getPassword())); user.privileges().addAll(getPrivileges()); return user; } diff --git a/src/main/java/com/monkeyk/sos/domain/dto/UserJsonDto.java b/src/main/java/com/monkeyk/sos/service/dto/UserJsonDto.java similarity index 97% rename from src/main/java/com/monkeyk/sos/domain/dto/UserJsonDto.java rename to src/main/java/com/monkeyk/sos/service/dto/UserJsonDto.java index c647908..2184996 100644 --- a/src/main/java/com/monkeyk/sos/domain/dto/UserJsonDto.java +++ b/src/main/java/com/monkeyk/sos/service/dto/UserJsonDto.java @@ -1,4 +1,4 @@ -package com.monkeyk.sos.domain.dto; +package com.monkeyk.sos.service.dto; import com.monkeyk.sos.domain.user.Privilege; import com.monkeyk.sos.domain.user.User; diff --git a/src/main/java/com/monkeyk/sos/domain/dto/UserOverviewDto.java b/src/main/java/com/monkeyk/sos/service/dto/UserOverviewDto.java similarity index 95% rename from src/main/java/com/monkeyk/sos/domain/dto/UserOverviewDto.java rename to src/main/java/com/monkeyk/sos/service/dto/UserOverviewDto.java index 9fc57ce..18fcb38 100644 --- a/src/main/java/com/monkeyk/sos/domain/dto/UserOverviewDto.java +++ b/src/main/java/com/monkeyk/sos/service/dto/UserOverviewDto.java @@ -1,4 +1,4 @@ -package com.monkeyk.sos.domain.dto; +package com.monkeyk.sos.service.dto; import java.io.Serializable; import java.util.ArrayList; diff --git a/src/main/java/com/monkeyk/sos/service/impl/OauthServiceImpl.java b/src/main/java/com/monkeyk/sos/service/impl/OauthServiceImpl.java index 97583a9..80077b4 100644 --- a/src/main/java/com/monkeyk/sos/service/impl/OauthServiceImpl.java +++ b/src/main/java/com/monkeyk/sos/service/impl/OauthServiceImpl.java @@ -1,6 +1,6 @@ package com.monkeyk.sos.service.impl; -import com.monkeyk.sos.domain.dto.OauthClientDetailsDto; +import com.monkeyk.sos.service.dto.OauthClientDetailsDto; import com.monkeyk.sos.domain.oauth.OauthClientDetails; import com.monkeyk.sos.domain.oauth.OauthRepository; import com.monkeyk.sos.service.OauthService; diff --git a/src/main/java/com/monkeyk/sos/service/impl/UserServiceImpl.java b/src/main/java/com/monkeyk/sos/service/impl/UserServiceImpl.java index 9e50d0c..eeb6aab 100644 --- a/src/main/java/com/monkeyk/sos/service/impl/UserServiceImpl.java +++ b/src/main/java/com/monkeyk/sos/service/impl/UserServiceImpl.java @@ -1,9 +1,9 @@ package com.monkeyk.sos.service.impl; -import com.monkeyk.sos.domain.dto.UserDto; -import com.monkeyk.sos.domain.dto.UserFormDto; -import com.monkeyk.sos.domain.dto.UserJsonDto; -import com.monkeyk.sos.domain.dto.UserOverviewDto; +import com.monkeyk.sos.service.dto.UserDto; +import com.monkeyk.sos.service.dto.UserFormDto; +import com.monkeyk.sos.service.dto.UserJsonDto; +import com.monkeyk.sos.service.dto.UserOverviewDto; import com.monkeyk.sos.domain.shared.security.WdcyUserDetails; import com.monkeyk.sos.domain.user.User; import com.monkeyk.sos.domain.user.UserRepository; diff --git a/src/main/java/com/monkeyk/sos/web/controller/ClientDetailsController.java b/src/main/java/com/monkeyk/sos/web/controller/ClientDetailsController.java index e2b59a0..4cdccf6 100644 --- a/src/main/java/com/monkeyk/sos/web/controller/ClientDetailsController.java +++ b/src/main/java/com/monkeyk/sos/web/controller/ClientDetailsController.java @@ -1,6 +1,6 @@ package com.monkeyk.sos.web.controller; -import com.monkeyk.sos.domain.dto.OauthClientDetailsDto; +import com.monkeyk.sos.service.dto.OauthClientDetailsDto; import com.monkeyk.sos.service.OauthService; import com.monkeyk.sos.web.oauth.OauthClientDetailsDtoValidator; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/monkeyk/sos/web/controller/OAuthRestController.java b/src/main/java/com/monkeyk/sos/web/controller/OAuthRestController.java index 7f779e7..99bbd3c 100644 --- a/src/main/java/com/monkeyk/sos/web/controller/OAuthRestController.java +++ b/src/main/java/com/monkeyk/sos/web/controller/OAuthRestController.java @@ -204,7 +204,7 @@ public class OAuthRestController implements InitializingBean, ApplicationContext @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (this.authenticationManager == null) { - this.authenticationManager = (AuthenticationManager) applicationContext.getBean("authenticationManager"); + this.authenticationManager = (AuthenticationManager) applicationContext.getBean("authenticationManagerBean"); } } } diff --git a/src/main/java/com/monkeyk/sos/web/controller/UserController.java b/src/main/java/com/monkeyk/sos/web/controller/UserController.java index a864592..3f241ff 100644 --- a/src/main/java/com/monkeyk/sos/web/controller/UserController.java +++ b/src/main/java/com/monkeyk/sos/web/controller/UserController.java @@ -1,7 +1,7 @@ package com.monkeyk.sos.web.controller; -import com.monkeyk.sos.domain.dto.UserFormDto; -import com.monkeyk.sos.domain.dto.UserOverviewDto; +import com.monkeyk.sos.service.dto.UserFormDto; +import com.monkeyk.sos.service.dto.UserOverviewDto; import com.monkeyk.sos.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/src/main/java/com/monkeyk/sos/web/controller/UserFormDtoValidator.java b/src/main/java/com/monkeyk/sos/web/controller/UserFormDtoValidator.java index 851add4..37245d9 100644 --- a/src/main/java/com/monkeyk/sos/web/controller/UserFormDtoValidator.java +++ b/src/main/java/com/monkeyk/sos/web/controller/UserFormDtoValidator.java @@ -1,6 +1,6 @@ package com.monkeyk.sos.web.controller; -import com.monkeyk.sos.domain.dto.UserFormDto; +import com.monkeyk.sos.service.dto.UserFormDto; import com.monkeyk.sos.domain.user.Privilege; import com.monkeyk.sos.service.UserService; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/com/monkeyk/sos/web/controller/mobile/MobileController.java b/src/main/java/com/monkeyk/sos/web/controller/mobile/MobileController.java index 27b290e..f4c7885 100644 --- a/src/main/java/com/monkeyk/sos/web/controller/mobile/MobileController.java +++ b/src/main/java/com/monkeyk/sos/web/controller/mobile/MobileController.java @@ -1,6 +1,6 @@ package com.monkeyk.sos.web.controller.mobile; -import com.monkeyk.sos.domain.dto.UserJsonDto; +import com.monkeyk.sos.service.dto.UserJsonDto; import com.monkeyk.sos.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/src/main/java/com/monkeyk/sos/web/controller/unity/UnityController.java b/src/main/java/com/monkeyk/sos/web/controller/unity/UnityController.java index b333ba8..4bfc491 100644 --- a/src/main/java/com/monkeyk/sos/web/controller/unity/UnityController.java +++ b/src/main/java/com/monkeyk/sos/web/controller/unity/UnityController.java @@ -1,6 +1,6 @@ package com.monkeyk.sos.web.controller.unity; -import com.monkeyk.sos.domain.dto.UserJsonDto; +import com.monkeyk.sos.service.dto.UserJsonDto; import com.monkeyk.sos.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/src/main/java/com/monkeyk/sos/web/filter/SOSSiteMeshFilter.java b/src/main/java/com/monkeyk/sos/web/filter/SOSSiteMeshFilter.java new file mode 100644 index 0000000..f8693de --- /dev/null +++ b/src/main/java/com/monkeyk/sos/web/filter/SOSSiteMeshFilter.java @@ -0,0 +1,31 @@ +package com.monkeyk.sos.web.filter; + +import org.sitemesh.builder.SiteMeshFilterBuilder; +import org.sitemesh.config.ConfigurableSiteMeshFilter; + +/** + * 2018/2/3 + *

+ * Replace decorator.xml + *

+ * Sitemesh + * + * @author Shengzhao Li + */ +public class SOSSiteMeshFilter extends ConfigurableSiteMeshFilter { + + + public SOSSiteMeshFilter() { + } + + + @Override + protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) { + + builder.addDecoratorPath("/*", "/WEB-INF/jsp/decorators/main.jsp") + + .addExcludedPath("/static/**"); + + + } +} diff --git a/src/main/java/com/monkeyk/sos/web/oauth/OauthClientDetailsDtoValidator.java b/src/main/java/com/monkeyk/sos/web/oauth/OauthClientDetailsDtoValidator.java index 37e7f8b..34a1e9c 100644 --- a/src/main/java/com/monkeyk/sos/web/oauth/OauthClientDetailsDtoValidator.java +++ b/src/main/java/com/monkeyk/sos/web/oauth/OauthClientDetailsDtoValidator.java @@ -1,6 +1,6 @@ package com.monkeyk.sos.web.oauth; -import com.monkeyk.sos.domain.dto.OauthClientDetailsDto; +import com.monkeyk.sos.service.dto.OauthClientDetailsDto; import com.monkeyk.sos.service.OauthService; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1022c0e..160157f 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -5,20 +5,19 @@ spring.application.name=spring-oauth-server # MySQL ##################### spring.datasource.driver-class-name=com.mysql.jdbc.Driver -spring.datasource.url=jdbc:mysql://localhost:3306/oauth2?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=utf8 +spring.datasource.url=jdbc:mysql://localhost:3306/oauth2_boot?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=utf8 spring.datasource.data-username=andaily spring.datasource.data-password=andaily # -#THYMELEAF +# MVC +spring.mvc.ignore-default-model-on-redirect=false +spring.http.encoding.enabled=true +spring.http.encoding.charset=UTF-8 +spring.http.encoding.force=true +spring.mvc.locale=zh_CN +spring.mvc.view.prefix=/WEB-INF/jsp/ +spring.mvc.view.suffix=.jsp # -spring.thymeleaf.prefix=/WEB-INF/view/ -spring.thymeleaf.suffix=.html -spring.thymeleaf.mode=HTML5 -spring.thymeleaf.encoding=UTF-8 -# ;charset= is added -spring.thymeleaf.content-type=text/html -# set to false for hot refresh -spring.thymeleaf.cache=false # # Logging # diff --git a/src/main/webapp/WEB-INF/decorators.xml b/src/main/webapp/WEB-INF/decorators.xml.old similarity index 100% rename from src/main/webapp/WEB-INF/decorators.xml rename to src/main/webapp/WEB-INF/decorators.xml.old diff --git a/src/main/webapp/WEB-INF/log4j.xml b/src/main/webapp/WEB-INF/log4j.xml.old similarity index 100% rename from src/main/webapp/WEB-INF/log4j.xml rename to src/main/webapp/WEB-INF/log4j.xml.old diff --git a/src/test/java/com/monkeyk/sos/infrastructure/PasswordHandlerTest.java b/src/test/java/com/monkeyk/sos/infrastructure/PasswordHandlerTest.java index e533215..b3cae00 100644 --- a/src/test/java/com/monkeyk/sos/infrastructure/PasswordHandlerTest.java +++ b/src/test/java/com/monkeyk/sos/infrastructure/PasswordHandlerTest.java @@ -14,7 +14,7 @@ public class PasswordHandlerTest { @Test public void testMd5() throws Exception { - final String md5 = PasswordHandler.md5("123456"); + final String md5 = PasswordHandler.encode("123456"); assertNotNull(md5); System.out.println(md5); }