我正在使用带有Java 7的Spring Boot 1.5.0,并且正在使用以下类来实现Oauth以保护REST API
1)AuthorizationServerConfiguration.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static String REALM="MY_OAUTH_REALM";
@Autowired
private TokenStore tokenStore;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
int accessTokenMinutesValidity = 60;
int refreshTokenMinutesValidity = 24 * 60;
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "client_credentials", "refresh_token")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.secret("{noop}secret")
.accessTokenValiditySeconds(60 * accessTokenMinutesValidity ).//Access token is only valid for 60 minutes.
refreshTokenValiditySeconds(60 * refreshTokenMinutesValidity);//Refresh token is only valid for 24 hours
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
.allowFormAuthenticationForClients()
.realm(REALM+"/client");
}
}
2)MethodSecurityConfig.java
import org.springframework.beans.factory.annotation.Autowired;
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;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
private OAuth2SecurityConfiguration securityConfig;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
3)OAuth2SecurityConfiguration.java
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
@SuppressWarnings("deprecation")
@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private DataSource dataSource;
@Primary
@Bean
public DataSource customDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
//dataSource properties set here
return dataSource;
}
@Bean
@ConfigurationProperties("spring.datasource")
public DataSource ds() {
return customDataSource();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
PasswordEncoder encoder = NoOpPasswordEncoder.getInstance();
BCryptPasswordEncoder enc;
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select USERNAME, ENC_PASSWD as PASSWORD, IS_ACTIVE AS ENABLED FROM USER_MSTR WHERE USERNAME=?")
.authoritiesByUsernameQuery("select USERNAME, 'ROLE_CLIENT' as ROLE from USER_MSTR where USERNAME=?")
.passwordEncoder(NoOpPasswordEncoder.getInstance())
;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Bean
@Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
4)ResourceServerConfiguration.java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_rest_api";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.requestMatchers()
.antMatchers("/category_mstr/**", "/equipment/**", "/param_mstr/**", "/chklist_txn/**", "/settings/**", "/user/**")
.and().authorizeRequests()
.antMatchers("/category_mstr/**", "/equipment/**", "/param_mstr/**", "/chklist_txn/**", "/settings/**", "/user/**")
.access("hasRole('ROLE_CLIENT')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
但是,访问/oauth/token
时,即使提供了适当的凭据,我也会收到一条错误消息,提示“凭据错误”
但是,如果我针对同一问题使用Java 8和Spring Boot 2.1.5,则它可以正常运行并按预期工作。
答案 0 :(得分:2)
由于可以使用密码编码器{noop}
来运行最新版本,因此不必添加旧版本{noop}
然后将其删除。