我使用OAuth2创建了一个授权服务器,目前,我可以在调用时获取一个持有者令牌:
public class Anything<T>
{
/// <summary>
/// Generic typed constructor
/// </summary>
/// <param name="param1"></param>
public Anything(T param1)
{
Console.WriteLine("I'm generic typed constructor");
}
/// <summary>
/// String typed constructor
/// </summary>
/// <param name="param1"></param>
public Anything(string param1)
{
Console.WriteLine("I'm string typed constructor");
}
}
我使用返回的令牌并向资源服务器发出请求,如下所示:
POST /oauth/token?grant_type=client_credentials&client_id=user-service&client_secret=userServicePassword&scope=server HTTP/1.1
Host: localhost:1002
Content-Type: application/json
Authorization: Basic dXNlci1zZXJ2aWNlOnVzZXJTZXJ2aWNlUGFzc3dvcmQ=
但是我得到了
POST /users/create HTTP/1.1
Host: localhost:1002
Content-Type: application/json
Authorization: Bearer 7ba026a4-2ae2-46be-8bd6-65d4aeb09dac
{
"username":"nicolasmanic",
"password":"12345",
"authorities":["ADMIN", "USER"]
}
我的OAuth2AuthorizationConfig
{
"timestamp": 1496657103659,
"status": 403,
"error": "Forbidden",
"exception": "org.springframework.security.access.AccessDeniedException",
"message": "Access Denied",
"path": "/users/create"
}
我的WebSecurityConfig
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
private static final String STORY_SERVICE_PASSWORD = "storyServicePassword";
private static final String USER_SERVICE_PASSWORD = "userServicePassword";
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private UserService userService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(new InMemoryTokenStore())
.authenticationManager(authenticationManager) //Enable password grant type.
.userDetailsService(userService);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("browser")
.authorizedGrantTypes("refresh_token", "password")
.scopes("ui")
.and()
.withClient("story-service")
.secret(STORY_SERVICE_PASSWORD)
.authorizedGrantTypes("client_credentials", "refresh_token")
.scopes("server")
.and()
.withClient("user-service")
.secret(USER_SERVICE_PASSWORD)
.authorizedGrantTypes("client_credentials", "refresh_token")
.scopes("server");
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
}
最后我的控制器
@Configuration
@Order(101)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userDetailsService;
/*
* Authenticate all urls except from home {/} and /login/* etc.
* */
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/","/login").permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
你知道我的配置错误吗?
修改
此处还有stacktrace:
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/current", method = RequestMethod.GET)
public Principal getUser(Principal principal) {
return principal;
}
@PreAuthorize("#oauth2.hasScope('server')")
@RequestMapping(value = "/create", method = RequestMethod.POST)
public void createUser(@Valid @RequestBody User user) {
userService.create(user);
}
}
答案 0 :(得分:1)
您必须将@EnableGlobalMethodSecurity
添加到OAuth2AuthorizationConfig类。
答案 1 :(得分:0)
终于明白了。
我已完成删除 WebSecurityConfig 。我将 GlobalAuthenticationConfigurerAdapter 扩展为:
@Configuration
public class GlobalAuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
@Autowired
UserRepository userRepository;
@Autowired
UserServiceImpl userService;
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authProvider());
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userService);
authProvider.setPasswordEncoder(new BCryptPasswordEncoder());
return authProvider;
}
@Bean
UserDetailsService userDetailsService() {
return (username) -> userRepository
.findByUsername(username);
}
}
我认为该问题与 userService 的自动装配有关。我曾经将它自动装入接口而不是实现 UserDetailsService 的具体类(userServiceImpl)。