无法在Spring OAuth2中使用访问令牌

时间:2018-02-17 03:20:06

标签: java spring-boot spring-oauth2

我从Spring Boot应用程序访问并刷新令牌:

curl -X POST -d "client_id=clientIdPassword&grant_type=password&username=test@gmail.com&password=123@Qwerty" -H "Authorization: Basic Y2xpZW50SWRQYXNzd29yZDpzZWNyZXQ=" http://localhost:8082/oauth/token

响应:

{
    "access_token":"b57f72b5-43c2-49ac-88ce-43d50e9d39b4",
    "token_type":"bearer",
    "refresh_token":"7d58c9a1-e924-4a9f-8583-01770d1f667c",
    "expires_in":41727,
    "scope":""
}

但是当我尝试使用此访问令牌发送请求时,我的应用会将我重定向到登录页面。

curl -X POST -GET -H "Authorization: Bearer b57f72b5-43c2-49ac-88ce-43d50e9d39b4" -v http://localhost:8082/users
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8082 (#0)
> POST /users HTTP/1.1
> Host: localhost:8082
> User-Agent: curl/7.55.1
> Accept: */*
> Authorization: Bearer b57f72b5-43c2-49ac-88ce-43d50e9d39b4
> 
< HTTP/1.1 302 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=93B47C0FB5A11A651BC0A12AC8FBE021; Path=/; HttpOnly
< Location: http://localhost:8082/login
< Content-Length: 0
< Date: Sat, 17 Feb 2018 03:10:38 GMT
< 
* Connection #0 to host localhost left intact

我的要求有什么问题?在我的控制器下面:

@RequestMapping("users")
@RestController
@EnableWebMvc
@Validated
public class UserController {

    @Autowired
    protected UserManager mUserManager;

    @PreAuthorize("#oauth2.hasScope('read')")
    @PostMapping(value = "new")
    public ResponseEntity<UserModel> add(@RequestBody NewUserModel newUser) {
        User user = UserUtils.toUser(mUserManager, newUser);

        if (!mUserManager.add(user)) {
            throw new InternalServerException(ServerError.INTERNAL);
        }

        UserModel model = new UserModel(user);

        return new ResponseEntity<>(model, HttpStatus.CREATED);
    }

    @GetMapping
    public Page<UserModel> all(@RequestParam(defaultValue = "0") int page) {
        return mUserManager.getUsers(page);
    }
}

我的配置:
OAuth2Config:

@Configuration
@EnableAuthorizationServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

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

    @Autowired
    private AppConfig mAppConfig;

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

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(mAppConfig.userDataSource())
                .withClient("sampleClientId")
                .authorizedGrantTypes("implicit")
                .scopes("read")
                .autoApprove(true)
                .and()
                .withClient("clientIdPassword")
                .secret("secret")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .scopes("read");
    }

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

ServerSecurityConfig:

@Configuration
public class ServerSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("test@gmail.com")
                .password("123@Qwerty")
                .roles("USER");
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }
}

P.S。我正在使用Sring Boot 1.5.9.RELEASE

2 个答案:

答案 0 :(得分:1)

你的spring-security配置是否不允许access_token url?您的配置可能需要有权访问access_token交换网址,然后重定向到登录页面。

您可以为此网址尝试permitAll(),然后重试。

=====更新=====

您的授权服务器是否与资源服务器位于同一项目中?如果是这样,我经常会发现您无法使用令牌访问受保护的URL。 在我的情况下,我必须将资源服务器和授权服务器分成两个项目,同时运行它们,然后我可以正确访问带有令牌的URL。

答案 1 :(得分:0)

查看你的范围。

作为无范围发出的令牌。

您的方法安全性要求您拥有范围&#34;阅读&#34;。