Spring启动:使用oauth2保护api端点,同时拥有mvc UI页面

时间:2015-12-09 03:54:45

标签: spring spring-mvc spring-security oauth-2.0 spring-boot

我正在尝试使用标准登录的spring-boot mvc应用程序,同时使用oAuth2安全性公开一些API端点。 基本上我的要求如下:

如果用户点击主页(“/”),请检查它是否已通过身份验证。 如果没有显示登录表单,则显示主页。 但是,用户还应该能够请求oauth身份验证令牌,并使用该令牌access / api / assignment / {id}。

我可以让标准登录工作,我可以让oauth2工作,但我不能让他们一起工作。

这是我目前的配置:

WebSecurityConfig

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private DataSource dataSource;

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);        
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {    
        auth.jdbcAuthentication().dataSource(this.dataSource).passwordEncoder(new BCryptPasswordEncoder());
    }
}

OAuth2Config

@Configuration
@EnableResourceServer
@EnableAuthorizationServer
public class OAuth2Config {

protected static final String RESOURCE_ID = "oauthdemo";

@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
      http          
      .httpBasic().disable()
      .authorizeRequests()
        .antMatchers("/js/**", "/css/**", "/images/**", "/webjars/**", "/login").permitAll()
          .anyRequest().authenticated()
          .and()
      .formLogin()
          .loginPage("/login")
          .permitAll()
          .and()
      .logout()
          .permitAll();

    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESOURCE_ID);
    }
}


@Configuration
@EnableAuthorizationServer
protected static class AuthServer extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.allowFormAuthenticationForClients();
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client")
                .authorizedGrantTypes("password", "refresh_token")
                .authorities("ROLE_USER")
                .scopes("read")
                .resourceIds(RESOURCE_ID)
                .secret("secret").accessTokenValiditySeconds(3600);
    }

}

}

问题是我在尝试打开主页时遇到以下错误(“/”)

<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>

它不会重定向到登录页面。 我不需要这个页面受oauth2保护,但即使我直接进入登录页面(“/ login”,我可以访问)并提供凭据,我仍然会得到“完全身份验证是必需的”错误。 即使我禁用了基本的http身份验证。

有谁知道如何将普通用户界面与需要受OAuth2保护的API端点分开?

2 个答案:

答案 0 :(得分:2)

你能试试吗

http          
      .authorizeRequests()
        .antMatchers("/js/**", "/css/**", "/images/**", "/webjars/**", "/login").permitAll()
         .antMatchers("/login").permitAll()
         .antMatchers("/home").authenticated();

考虑/ home是需要授权的页面。

答案 1 :(得分:1)

您必须在需要的情况下指定用于每个配置的过滤器:

在网络安全配置中

        http
        .authorizeRequests()
            .antMatchers("/api/**","/oauth/**")
            .permitAll()
            .and()
            .......

这将使Web安全性绕过授权/资源服务器URL

和资源服务器安全配置

        http
        .antMatcher("/api/**")
            .authorizeRequests()
            .anyRequest()
            .authenticated();

这将使资源安全绕过除“/ api /**".

之外的所有URL

通过这种方式你可以忽略配置顺序还有另一种选择,通过做出上述操作之一并使用@Order

按早期顺序放置其配置