这篇文章是对我以前的文章的增强,该文章讨论了如何使用Spring security oauth2保护REST API。
万一您错过了它,可以在这里领取: http : //blog.rajithdelantha.com/2015/09/secure-your-rest-api-with-spring.html
Spring Boot是Spring框架的一项新发明,它使开发人员在构建大规模应用程序时的工作更加轻松。 这是抓住概念的好地方。
如果您查看我之前有关oauth2安全的文章,那么您知道在Spring端需要做一些配置。 但是另一方面,Spring boot将完成所有艰苦的工作,我们只需要通过简单的注释告诉他们该怎么做。
因此,本文是关于如何使用Spring安全性和Oauth2配置Spring引导项目的。 实际上,我们不能真正说出configure,因为所有大多数配置都是由Spring boot本身完成的。
- 源代码: https : //github.com/rajithd/spring-boot-oauth2
步骤1
对于这个项目,我在内存数据库中使用H2。 因此,您无需在运行时创建任何数据库和表。 但是,如果您希望该项目使用MySQL作为数据源,则首先创建数据库,然后创建表。
CREATE TABLE user ( username VARCHAR(50) NOT NULL PRIMARY KEY, email VARCHAR(50), password VARCHAR(500), activated BOOLEAN DEFAULT FALSE, activationkey VARCHAR(50) DEFAULT NULL, resetpasswordkey VARCHAR(50) DEFAULT NULL ); CREATE TABLE authority ( name VARCHAR(50) NOT NULL PRIMARY KEY ); CREATE TABLE user_authority ( username VARCHAR(50) NOT NULL, authority VARCHAR(50) NOT NULL, FOREIGN KEY (username) REFERENCES user (username), FOREIGN KEY (authority) REFERENCES authority (name), UNIQUE INDEX user_authority_idx_1 (username, authority) ); CREATE TABLE oauth_access_token ( token_id VARCHAR(256) DEFAULT NULL, token BLOB, authentication_id VARCHAR(256) DEFAULT NULL, user_name VARCHAR(256) DEFAULT NULL, client_id VARCHAR(256) DEFAULT NULL, authentication BLOB, refresh_token VARCHAR(256) DEFAULT NULL ); CREATE TABLE oauth_refresh_token ( token_id VARCHAR(256) DEFAULT NULL, token BLOB, authentication BLOB );
- 用户表–系统用户
- 权威–角色
- user_authority –用户和角色的多对多表
- oauth_access_token –存放access_token
- oauth_refresh_token –保持refresh_token
添加一些种子数据。
INSERT INTO user (username,email, password, activated) VALUES ('admin', 'admin@mail.me', 'b8f57d6d6ec0a60dfe2e20182d4615b12e321cad9e2979e0b9f81e0d6eda78ad9b6dcfe53e4e22d1', true); INSERT INTO user (username,email, password, activated) VALUES ('user', 'user@mail.me', 'd6dfa9ff45e03b161e7f680f35d90d5ef51d243c2a8285aa7e11247bc2c92acde0c2bb626b1fac74', true); INSERT INTO user (username,email, password, activated) VALUES ('rajith', 'rajith@abc.com', 'd6dfa9ff45e03b161e7f680f35d90d5ef51d243c2a8285aa7e11247bc2c92acde0c2bb626b1fac74', true); INSERT INTO authority (name) VALUES ('ROLE_USER'); INSERT INTO authority (name) VALUES ('ROLE_ADMIN'); INSERT INTO user_authority (username,authority) VALUES ('rajith', 'ROLE_USER'); INSERT INTO user_authority (username,authority) VALUES ('user', 'ROLE_USER'); INSERT INTO user_authority (username,authority) VALUES ('admin', 'ROLE_USER'); INSERT INTO user_authority (username,authority) VALUES ('admin', 'ROLE_ADMIN');
第2步
配置WebSecurityAdapter
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new StandardPasswordEncoder(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()); } @Override public void configure(WebSecurity web) throws Exception { web .ignoring() .antMatchers("/h2console/**") .antMatchers("/api/register") .antMatchers("/api/activate") .antMatchers("/api/lostpassword") .antMatchers("/api/resetpassword"); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) private static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration { @Override protected MethodSecurityExpressionHandler createExpressionHandler() { return new OAuth2MethodSecurityExpressionHandler(); } } }
第三步
Oauth2的配置
@Configuration public class OAuth2Configuration { @Configuration @EnableResourceServer protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @Autowired private CustomAuthenticationEntryPoint customAuthenticationEntryPoint; @Autowired private CustomLogoutSuccessHandler customLogoutSuccessHandler; @Override public void configure(HttpSecurity http) throws Exception { http .exceptionHandling() .authenticationEntryPoint(customAuthenticationEntryPoint) .and() .logout() .logoutUrl("/oauth/logout") .logoutSuccessHandler(customLogoutSuccessHandler) .and() .csrf() .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")) .disable() .headers() .frameOptions().disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers("/hello/**").permitAll() .antMatchers("/secure/**").authenticated(); } } @Configuration @EnableAuthorizationServer protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter implements EnvironmentAware { private static final String ENV_OAUTH = "authentication.oauth."; private static final String PROP_CLIENTID = "clientid"; private static final String PROP_SECRET = "secret"; private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds"; private RelaxedPropertyResolver propertyResolver; @Autowired private DataSource dataSource; @Bean public TokenStore tokenStore() { return new JdbcTokenStore(dataSource); } @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(tokenStore()) .authenticationManager(authenticationManager); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients .inMemory() .withClient(propertyResolver.getProperty(PROP_CLIENTID)) .scopes("read", "write") .authorities(Authorities.ROLE_ADMIN.name(), Authorities.ROLE_USER.name()) .authorizedGrantTypes("password", "refresh_token") .secret(propertyResolver.getProperty(PROP_SECRET)) .accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800)); } @Override public void setEnvironment(Environment environment) { this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH); } } }
就是这个。 尝试通过mvn spring-boot:run运行Spring Boot应用程序
然后通过执行以下curl检查oauth2的安全性:
- https://github.com/rajithd/spring-boot-oauth2
翻译自: https://www.javacodegeeks.com/2015/10/spring-boot-oauth2-security.html