Я пытаюсь использовать Spring Security oauth2 для контроля доступа с помощью аннотаций, таких как @PreAuthorize ("hasAuthority ('perm2')") или конфигурации безопасности в WebSecurityConfigurerAdapter. Но я всегда получаю 403 запрета, когда пытаюсь получить доступAPI, аннотированный @PreAuthorize ("hasAuthority ('perm2')") после того, как я вхожу в систему пользователем, у которого есть полномочия 'perm2'. Я установил точку останова в ClientDetailsUserDetailsService, но загруженные UserDetails не содержали никаких прав доступа. Более того, я обнаружил,чтобы я мог извлечь полномочия, содержащие «perm2», из AuthoritiesExtractor.
Один из способов сделать это - переписать UserDetailService, чтобы я мог установить полномочия для UserDetails AuthoritiesExtractor.Но мой вопрос:
Это лучшая практика?или я просто пропускаю что-то еще?
Ниже приведен мой пробный код, за которым следует учебник по baeldung
мой код авторизации здесь
@SpringBootApplication
@EnableResourceServer
@RestController
public class App extends SpringBootServletInitializer {
@GetMapping("/user/me")
public Principal user(Principal principal) {
return principal;
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Configuration
@EnableAuthorizationServer
public static class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
public void configure(
AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("SampleClientId")
.secret(passwordEncoder.encode("secret"))
.authorizedGrantTypes("authorization_code")
.scopes("user_info")
.autoApprove(true)
.redirectUris("http://localhost:8082/ui/login", "http://localhost:8083/ui2/login");
}
}
@Configuration
@Order(1)
public static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.antMatchers("/login", "/oauth/authorize")
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("john")
.password(passwordEncoder().encode("123"))
.roles("USER").authorities("perm1").and()
.withUser("tom")
.password(passwordEncoder().encode("123"))
.roles("USER")
.authorities("perm1", "perm2");
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
моя конфигурация клиента здесь:
@Configuration
@EnableOAuth2Sso
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled =true)
public class App extends WebSecurityConfigurerAdapter {
@Bean
AuthoritiesExtractor authoritiesExtractor(){
return new FixedAuthoritiesExtractor();
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**")
.permitAll()
.anyRequest()
.hasAuthority("perm1").anyRequest()
.authenticated();
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
и это мой контроллер:
@Controller
public class MyController {
@GetMapping("/securedPage")
@PreAuthorize("hasAuthority('perm2')")
public String securedPage() {
return "securedPage";
}
@GetMapping("/testPerm")
@PreAuthorize("hasAuthority('perm3')")
public @ResponseBody
String testPerm() {
return "This could not be happened!";
}
}
То, что я ожидаю, это:
когда я захожу с john, я получаю запрет при доступеsecuredPage.
Но когда я захожу с Томом, я могу получить доступ к securedPage.
Дело в том, что, кто бы я ни входил, я получаю запрещенную страницу ниже
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri May 24 11:29:09 CST 2019
There was an unexpected error (type=Forbidden, status=403).
Forbidden