spring security + oauth2 + mysql + database authentication

时间:2017-05-05 13:50:40

标签: mysql spring-boot jwt spring-security-oauth2

我正在使用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
        }


    }
}

0 个答案:

没有答案