我正在使用oauth2身份验证处理spring security。以前对于授权服务器中的客户端详细信息服务,我使用内存机制,它工作得很好。现在我想使用数据库进行客户端详细信息服务。我正在使用Mysql数据库。请为数据库配置客户端详细信息服务提供一些解决方案。
我正在共享我的授权服务器配置类:
@SpringBootApplication
@Controller
@SessionAttributes("authorizationRequest")
@EnableResourceServer
public class AuthServerApplication extends WebMvcConfigurerAdapter {
@RequestMapping("/user")
@ResponseBody
public Principal user(Principal user) {
return user;
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/oauth/confirm_access").setViewName("authorize");
}
public static void main(String[] args) {
SpringApplication.run(AuthServerApplication.class, args);
}
@Configuration
protected static class CorsFilterConfig {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
// we want this to run before the SpringSecurityFilterChain which we set at 50 in properties
// anything less than 50 will work
bean.setOrder(0);
return bean;
}
}
@Configuration
//@Order(-20)
protected static class LoginConfig extends WebSecurityConfigurerAdapter{
@Autowired
@Qualifier("authenticationManager")
private AuthenticationManager authenticationManager;
@Autowired
private CustomUserDetailsService userDetailsService;
/**
* '/oauth/authorize' is AuthorizationEndPoint and it's used to service requests for authorization.
* '/oauth/confirm_access' endpoint - User approval for Grants here.
* Authorization endpoint /oauth/authorize (or its mapped alternative) should be protected using Spring Security so that it is only accessible to authenticated users
* Authorization endpoint is used to grant authorization to client application
* The TokenEndPoint is protected by default by spring oauth in the @Configuration support using HttpBasicAuthentication of the client secret
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin() // Allows users to authenticate with form based login
.loginPage("/login") // location of log in page
.permitAll() // grant access to all users to access to our log in page
.and()
.requestMatchers()
.antMatchers("/login","/oauth/authorize", "/oauth/confirm_access") // These URL's any user can access
.and()
.authorizeRequests().anyRequest().authenticated(); // Any other request to our application requires the user to be authenticated
// .and()
// .rememberMe()
// .key("uniqueAndSecret")
// .tokenValiditySeconds(86400);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.parentAuthenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
// auth
// .inMemoryAuthentication()
// .withUser("roy").password("spring").roles("USER");
}
}
/*
* EnableAuthorizationServer annotation is used to configure the oauth2.0 Authorization Server Mechanism together with any beans that implement AuthorizationServerConfigurer
*
*/
@Configuration
@EnableAuthorizationServer
protected static class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManager")
private AuthenticationManager authenticationManager;
@Autowired
private ApplicationContext context;
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory(
new ClassPathResource("keystore.jks"), "suleman123".toCharArray())
.getKeyPair("resourcekey");
converter.setKeyPair(keyPair);
return converter;
}
// @Bean
// public DataSource dataSource(){
// //jdbc:hsqldb:mem:testdb
// EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
// EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.HSQL)
// .addScript("classpath:schema.sql")
// .addScript("classpath:data.sql")
// .build();
// return db;
// }
/*
* A configurer that defines the client details service.
* ClientDetailsServiceConfigurer is used to define an in-memory or JDBC implementation of the client details service.
*
* A authorization code is obtained by the OAuth client by directing the end-user to an authorization page where the user can enter
* his/her credentials, resulting in a redirection from the provider authorization server back to the OAuth client with the authorization code
*
* We registered the client and authorized for the 'authorization_code', 'refresh_token', 'password' grant types
*
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// clients.inMemory()
// .withClient("acme") //(required) the client id.
// .secret("acmesecret") //(required for trusted clients) the client secret, if any.
// .authorizedGrantTypes("authorization_code", "refresh_token",
// "password") // Grant types that the client is to use to obtain an access token
// .accessTokenValiditySeconds(5)
// .scopes("openid") // scope to which the client is limited
// .autoApprove(true);
DriverManagerDataSource dataSource = (DriverManagerDataSource)context.getBean("dataSource");
clients.jdbc(dataSource);
}
/**
* Defines the authorization and token end point and token services
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter());
}
/**
* defines the security constraints on the token end point
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
//
oauthServer.tokenKeyAccess("permitAll()") // It open the access to public key exposed by the authorization server on the end point /oauth/token_key
.checkTokenAccess("isAuthenticated()"); // check it is authenticated or not
}
}
}