具有OAuth2和自定义身份验证提供程序的Spring Boot REST服务

时间:2018-12-15 21:22:47

标签: java spring rest spring-boot oauth-2.0

我正在基于spring greeting example构建REST服务。这很好,我对春天拯救我的时间感到非常满意。今天,我试图通过访问令牌和刷新令牌来确保OAuth2安全。当我使用将用户名和密码存储在自己的存储库中的示例时,这可以很好地工作。关键是我需要一个自定义的身份验证提供程序,因为我需要向第三方系统进行身份验证,该系统将提供用户名和密码,返回真或假。

我确实找到了自定义安全提供程序的示例,但没有发现任何有关AuthorizationServer,ResourceServer,SecurityServer和自定义AuthorizationServer的示例的例子。

我无法合并所有示例,因为它们都稍有不同。...

在此先感谢您的帮助!

此致

彼得

1 个答案:

答案 0 :(得分:0)

@Configuration
@EnableAuthorizationServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter{

     @Autowired
        private AuthenticationManager authenticationManager;

        @Autowired
        private UserDetailsService userDetailsService;

        @Bean
        public WebResponseExceptionTranslator loggingExceptionTranslator() {
            return new DefaultWebResponseExceptionTranslator() {
                @Override
                public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
                    // This is the line that prints the stack trace to the log. You can customise this to format the trace etc if you like
                    e.printStackTrace();

                    // Carry on handling the exception
                    ResponseEntity<OAuth2Exception> responseEntity = super.translate(e);
                    HttpHeaders headers = new HttpHeaders();
                    headers.setAll(responseEntity.getHeaders().toSingleValueMap());
                    OAuth2Exception excBody = responseEntity.getBody();
                    return new ResponseEntity<>(excBody, headers, responseEntity.getStatusCode());
                }
            };
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory().withClient("webapp")
                    .secret("{bcrypt}$2a$10$kwz.jnLVLwJOYTAp2r/oG.8tfAN/EC5dK1w5beLgfpuFT6Puprgq.")
                    .authorizedGrantTypes("implicit", "password", "authorization_code", "refresh_toke")
                    .scopes("read", "write").accessTokenValiditySeconds(3600 * 8).refreshTokenValiditySeconds(3600 * 8);
        }

        @Override
        public void configure(AuthorizationServerSecurityConfigurer configurer) throws Exception {
            configurer.tokenKeyAccess("permitAll()")
                    .checkTokenAccess("isAuthenticated()");
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
            enhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), jwtAccessTokenConverter()));

            endpoints
                    .authenticationManager(this.authenticationManager)
                    .accessTokenConverter(jwtAccessTokenConverter())
                    .tokenEnhancer(enhancerChain)
                    .userDetailsService(userDetailsService)
                    .exceptionTranslator(loggingExceptionTranslator());
        }


        @Bean
        public TokenEnhancer tokenEnhancer() {
            return (accessToken, authentication) -> {
                MyPrincipal userDetails = (MyPrincipal)userDetailsService.loadUserByUsername(authentication.getName());
                Map<String, Object> additionalInfor = new HashMap<>();
                additionalInfor.put("accountName", userDetails.getUsername());
                additionalInfor.put("authorities", userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
                ((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfor);
                return accessToken;
            };
        }

        @Bean
        UserAuthenticationConverter userAuthenticationConverter() {
            DefaultUserAuthenticationConverter converter = new DefaultUserAuthenticationConverter();
            converter.setUserDetailsService(userDetailsService);
            return converter;
        }

        @Bean
        AccessTokenConverter accessTokenConverter() {
            DefaultAccessTokenConverter converter = new DefaultAccessTokenConverter();
            converter.setUserTokenConverter(userAuthenticationConverter());
            return converter;
        }

        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setAccessTokenConverter(accessTokenConverter());
            converter.setSigningKey("123");
            return converter;
        }

        @Bean
        public FilterRegistrationBean corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration configuration = new CorsConfiguration();
            configuration.setAllowCredentials(true);
            configuration.addAllowedOrigin("*");
            configuration.addAllowedHeader("*");
            configuration.addAllowedMethod("*");
            source.registerCorsConfiguration("/**", configuration);
            FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
            bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
            return bean;
        }


}