我正在尝试在Spring Boot应用程序中实现OAuth2。到目前为止,我已经能够获取访问令牌并能够访问url,但是我感到困惑,当我在应用程序中启用资源服务器配置时,具有USER角色的用户可以访问ADMIN页面,反之亦然。并且Authentication
设置为true
,其中authentication.getName()
从username
请求oauth2
返回到grant_type=password
框架:
我的代码如下:
SecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private LoginRepository loginRepository;
@Autowired
private TestLoginService testLoginService;
@Autowired
private DaoAuthenticationProvider daoAuthenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/register").permitAll()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.httpBasic();
}
@Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Override
protected UserDetailsService userDetailsService() {
loginRepository.init(encoder());
return testLoginService;
}
@Bean
public DaoAuthenticationProvider customAuthenticationProvider() {
final DaoAuthenticationProvider customAuthenticationProvider = new DaoAuthenticationProvider();
customAuthenticationProvider.setUserDetailsService(testLoginService);
customAuthenticationProvider.setPasswordEncoder(encoder());
return customAuthenticationProvider;
}
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
OAuth2SecurityConfig.java
@Configuration
@EnableAuthorizationServer
public class OAuth2SecurityConfig extends AuthorizationServerConfigurerAdapter {
private static Logger logger = LoggerFactory.getLogger(OAuth2SecurityConfig.class);
@Autowired
private TokenStore tokenStore;
@Autowired
private AuthenticationManager AuthenticationManager;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore)
.authenticationManager(AuthenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secret = passwordEncoder.encode("secret");
logger.info("Secret : " + secret);
clients
.inMemory()
.withClient("client")
.secret("$2a$10$8ip4rySjPLcCedGRVgvT8OriH7dB2VoWDQfk7V3mvPx/BBV8Yglry")
.autoApprove(false)
.authorizedGrantTypes("password", "authorization_code", "implicit", "refresh_token")
.scopes(Role.ROLE_USER.name(), Role.ROLE_ADMIN.name())
.redirectUris("http://localhost:8080/code")
.accessTokenValiditySeconds(3600)
.refreshTokenValiditySeconds(4800);
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
}
OAuth2ResourceSecurityConfig.java
@Configuration
@EnableResourceServer
public class OAuth2ResourceSecurityConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated();
}
}
如果我未配置OAuth2ResourceSecurityConfig#configure方法,则用户或管理员角色用户可以访问任何一个URL。有人可以向我解释OAuth2ResourceSecurityConfig
和SecurityConfig
中configure方法的相关性,以及应该使用哪种方法来更好地说明问题。
SecurityController.java
@RequestMapping(value = "/admin", method = RequestMethod.GET)
public String adminAccess(Authentication authentication) {
logger.info("Admin access /admin link: " + authentication.getName() + " role: " + authentication.getAuthorities().toString());
logger.info("Admin User authenticated: " + authentication.isAuthenticated());
return authentication.getName();
}
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String userAccess(Authentication authentication) {
logger.info("User access / : " + authentication.getName() + " role: " + authentication.getAuthorities().toString());
logger.info("User authenticated: " + authentication.isAuthenticated());
return authentication.getName();
}
谢谢。