2017-03-15 91 views
2

我有OAuth2用户安全一个春天启动REST API。SpringBoot为1.5.x +安全+的OAuth2

今天我已将我的版本spring-boot-starter-parent1.4.2升级到1.5.2

变化完全搞糊涂了。

之前,我可以测试我的邮差REST API。当我的访问令牌是不正确的或我没有特定资源权限,服务器响应,如:

{ 
    "error": "access_denied", 
    "error_description": "Access is denied" 
} 

现在它使重定向我/login页......当我登录 - 它显示我的资源没有任何OAuth2用户认证...

我试图禁用它,我发现这个神奇的属性:

security.oauth2.resource.filter-order = 3 

此线时截止重定向到登录页面。

不过,我的问题是:在安全性来看,这些2个版本之间

  • 发生了什么?
  • 是这个“奇怪”的行是唯一有效的解决?
  • 这是什么登录页面的目的,它使用什么身份验证(我检查了谷歌浏览器的请求和响应,我看不到任何的访问令牌和的oauth2的东西,所以它是一个使用用户库,然后只?)

我的代码一些更重要的部分:

的pom.xml

<!--- .... --> 
<parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.5.2.RELEASE</version> 
</parent> 
<properties> 
    <!--- .... --> 
    <spring-security-oauth.version>2.1.0.RELEASE</spring-security-oauth.version> 
    <!--- .... --> 
</properties> 
<dependencies> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-data-jpa</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
    <!-- Monitor features --> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-actuator</artifactId> 
    </dependency> 
    <!-- Security + OAuth2 --> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-security</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.security.oauth</groupId> 
     <artifactId>spring-security-oauth2</artifactId> 
     <version>${spring-security-oauth.version}</version> 
    </dependency> 
<!--- .... --> 

application.properties

#other properties 
security.oauth2.resource.filter-order = 3 

OAuth2.java

public class OAuth2 { 
@EnableAuthorizationServer 
@Configuration 
@ComponentScan 
public static class AuthorizationServer extends AuthorizationServerConfigurerAdapter { 

    @Autowired 
    private AuthenticationManager authenticationManagerBean; 
    @Autowired 
    private UserDetailsService userDetailsService; 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.inMemory() 
       .withClient("trusted_client") 
       .authorizedGrantTypes("password", "refresh_token") 
       .scopes("read", "write"); 
    } 

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

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

@EnableResourceServer 
@Configuration 
@ComponentScan 
public static class ResourceServer extends ResourceServerConfigurerAdapter { 

    @Autowired 
    private RoleHierarchy roleHierarchy; 

    private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() { 
     DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler(); 
     defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy); 
     return defaultWebSecurityExpressionHandler; 
    } 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     http 
       .authorizeRequests().expressionHandler(webExpressionHandler()) 
       .antMatchers("/api/**").hasRole("DEVELOPER"); 
    } 
} 
} 

Security.java

@EnableWebSecurity 
@Configuration 
@ComponentScan 
public class Security extends WebSecurityConfigurerAdapter { 

@Autowired 
private UserDetailsService userDetailsService; 

@Bean 
public JpaAccountDetailsService userDetailsService(AccountsRepository accountsRepository) { 
    return new JpaAccountDetailsService(accountsRepository); 
} 

@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); 
} 

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

@Bean 
public PasswordEncoder passwordEncoder(){ 
    return new BCryptPasswordEncoder(); 
} 
} 

回答

7

好的,我现在明白了。

@Cleto Gadelha指给我非常有用的信息。

但是,我认为发布说明还不清楚或缺少一些信息。除了OAuth2资源过滤器从3更改为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1,关键信息是默认WebSecurityConfigurerAdapter订单是100 (source)

因此,在版本1.5.x之前,OAuth2资源服务器顺序为3,其中有较高,优先,然后是WebSecurityConfigurerAdapter

后发布1.5.X的OAuth2资源服务器顺序设置为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1 (这是Integer.MAX_VALUE - 8我认为),其中有现在可以肯定优先级则基本WebSecurityConfigurerAdapter秩序。

这就是为什么登录页面时,我从后的1.4.x迁移到1.5.x的

所以,更优雅和java般的风格的解决方案是设置@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)WebSecurityConfigurerAdapter

+0

尼斯调查。谢谢。 –

3

你的第一和第二个问题的答案是在Spring Boot 1.5 Release Notes

.本的 执行端点后放置它,但基本认证过滤器链前 -

的OAuth 2资源筛选

的OAuth2用户资源滤波器的默认顺序从3到 SecurityProperties.ACCESS_OVERRIDE_ORDER改变。 默认可以通过设置 security.oauth2.resource恢复。filter-order = 3

/login页面只是一个弹簧重定向未授权用户的路径。由于您没有使用Custom Login Form而您的Oauth2过滤器位置错误,因此可能是使用了基本身份验证。