【问题标题】:Spring Boot Rest service with oAuth2 Security credentials from database带有来自数据库的 oAuth2 安全凭证的 Spring Boot Rest 服务
【发布时间】:2015-04-09 05:15:04
【问题描述】:

谁能帮我举一个 Spring Boot 应用程序的示例,该应用程序包含一个 Rest Service,其端点受 Spring Security 保护,使用 oAuth2 和来自 MySQL 数据库的用户凭据?

【问题讨论】:

    标签: rest jpa oauth-2.0 spring-boot


    【解决方案1】:

    这个呢:https://github.com/spring-projects/spring-security-oauth/tree/master/tests/annotation/jdbc(不是 MySQL,是 JDBC,所以转换很简单)?

    【讨论】:

    • 谢谢戴夫。我对spring security还是很陌生。 Spring boot 使创建 RESTful 服务变得非常容易,但我仍然不清楚使用 oAuth2 和数据库凭据实现安全性。我看到一些 pre-Spring Boot 项目在数据库中创建令牌和刷新表。这不再是惯例了吗? github.com/royclarkson/spring-rest-service-oauth 使用内存认证。是否优先将令牌存储在数据库中?
    • 该链接包含您提到的架构的 SQL 文件(它们在内存数据库启动时执行,但您可以自己为 mysql 执行它们)。 Roy 的示例类似(并且同样最小),但内存中的用户存储显然不会在大多数系统的生产环境中有用。
    【解决方案2】:

    请参考https://github.com/royclarkson/spring-rest-service-oauth/ 并执行以下更改,它使用 application.properties 中定义的主数据源,

    @Configuration
    public class OAuth2ServerConfiguration {
    
        private static final String RESOURCE_ID = "rest_api";
    
        @Configuration
        @EnableResourceServer
        protected static class ResourceServerConfiguration extends
                ResourceServerConfigurerAdapter {
    
            @Override
            public void configure(ResourceServerSecurityConfigurer resources) {
                resources.resourceId(RESOURCE_ID);
            }
    
            @Override
            public void configure(HttpSecurity http) throws Exception {
                http.authorizeRequests()
                        .antMatchers("/users").hasRole("ADMIN")
                        .antMatchers("/review").authenticated()
                        .antMatchers("/logreview").authenticated()
                        .antMatchers("/oauth/token").authenticated()
                        .and()
                        .csrf()
                        .csrfTokenRepository(csrfTokenRepository()).and()
                        .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
                        ;
                }
    
                private Filter csrfHeaderFilter() {
                    return new OncePerRequestFilter() {
    
                        @Override
                        protected void doFilterInternal(HttpServletRequest request,
                                HttpServletResponse response, FilterChain filterChain)
                                throws ServletException, IOException {
    
                            CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                                    .getName());
                             if (csrf != null) {
                                Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                                String token = csrf.getToken();
                                if (cookie == null || token != null
                                        && !token.equals(cookie.getValue())) {
                                    cookie = new Cookie("XSRF-TOKEN", token);
                                    cookie.setPath("/");
                                    response.addCookie(cookie);
                                }
                            }
                            filterChain.doFilter(request, response);
                        }
                    };
                }
                private CsrfTokenRepository csrfTokenRepository() {
                    HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
                    repository.setHeaderName("X-XSRF-TOKEN");
                    return repository;
                }
            }
    
    
        @Configuration
        @EnableAuthorizationServer
        protected static class AuthorizationServerConfiguration extends
                AuthorizationServerConfigurerAdapter {
    
    
            @Autowired
            @Qualifier("authenticationManagerBean")
            private AuthenticationManager authenticationManager;
    
            @Autowired
            DataSource dataSource;
    
    
            @Override
            public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                    throws Exception {
    
                endpoints
                    .tokenStore(new JdbcTokenStore(dataSource))
                    .authenticationManager(this.authenticationManager);
    
            }
    
            @Override
            public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                clients
                    .jdbc(dataSource);
            }
    
            @Bean
            @Primary
            public DefaultTokenServices tokenServices() {
                DefaultTokenServices tokenServices = new DefaultTokenServices();
                tokenServices.setSupportRefreshToken(true);
                tokenServices.setAccessTokenValiditySeconds(300);
                tokenServices.setRefreshTokenValiditySeconds(6000);
                tokenServices.setTokenStore(new JdbcTokenStore(dataSource));
                return tokenServices;
            }
    
    
        }
    }
    

    【讨论】:

    • 嗨,我是新手,但由于某些原因,我不适用于 POST 请求。 {"error":"access_denied","error_description":"未找到预期的 CSRF 令牌。您的会话是否已过期?"} 它适用于 GET 方法
    • 遇到同样的问题,您找到解决方案了吗?
    猜你喜欢
    • 2019-05-16
    • 2017-03-13
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 2017-12-15
    • 2017-05-25
    • 2015-01-31
    相关资源
    最近更新 更多