Javaの設定でSpring SecurityとOAuth2を設定しようとしています。私はSpring Securityバージョン4.0.4.RELEASEとOAuth2バージョン2.0.11.RELEASEを使用しています。Oauth2リソースサーバーがSpring Securityの設定と重複しています
スプリングセキュリティの設定がうまく機能します。また、OAuth2 AuthorizationServerでアクセストークンを取得できますが、ResourceServerが正しく動作しません。注釈@EnableResourceServerを設定すると、自分のアクセストークン、および開くことができない他のURL(セキュリティ設定とAuthorizationServer設定が機能しない)だけをチェックできます。次のエラーが表示されます。
<oauth>
<error_description>
An Authentication object was not found in the SecurityContext
</error_description>
<error>unauthorized</error>
</oauth>
注釈@EnableResourceServerを削除すると、私のResourceServerはアクセストークンをチェックしません。認証ページにリダイレクトされます。
これは私のコードです:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class GlobalSecurityConfig extends GlobalMethodSecurityConfiguration {
@Bean(name = "passwordEncoder")
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
@Qualifier("authUserDetailsService")
private UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Autowired
@Qualifier("permissionEvaluator")
private PermissionEvaluator permissionEvaluator;
@Bean
public DefaultMethodSecurityExpressionHandler expressionHandler() {
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
handler.setDefaultRolePrefix("");
handler.setPermissionEvaluator(permissionEvaluator);
return handler;
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return expressionHandler();
}
}
SecurityConfig:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean(name = "clientAuthenticationEntryPoint")
public OAuth2AuthenticationEntryPoint oauthAuthenticationEntryPoint() {
OAuth2AuthenticationEntryPoint entry = new OAuth2AuthenticationEntryPoint();
entry.setRealmName("myapp/client");
entry.setTypeName("Basic");
return entry;
}
@Autowired
@Qualifier("webExpressionHandler")
private DefaultWebSecurityExpressionHandler expressionHandler;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/html/**", "/webapi/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/admin/**", "/**")
.and()
.authorizeRequests()
.expressionHandler(expressionHandler)
.antMatchers("/admin/**").access("hasRole('ADMINISTRATOR')")
.antMatchers("/1/admin/**").access("hasRole('ADMINISTRATOR')")
.antMatchers("/profile**").authenticated()
.antMatchers("/oauth/authorize").authenticated()
.and()
.formLogin().loginPage("/login")
.failureUrl("/login?error=1")
.loginProcessingUrl("/login-attempt")
.defaultSuccessUrl("/", false)
.and()
.sessionManagement()
.sessionFixation().migrateSession()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied")
.and()
.csrf();
}
}
のOAuth設定:だから
@Configuration
public class Oauth {
@Configuration
@EnableResourceServer
public static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_oauth_server";
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.regexMatchers("/api/v0/.*").authenticated()
.antMatchers("/**").denyAll()
;
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private AuthorizationCodeServices verificationCodeService;
@Autowired
@Qualifier("clientDetails")
private ClientDetailsService clientDetailsService;
@Autowired
@Qualifier("tokenStore")
private TokenStore tokenStore;
@Bean(name = "tokenServices")
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore);
tokenServices.setSupportRefreshToken(true);
tokenServices.setClientDetailsService(clientDetailsService);
return tokenServices;
}
@Bean
public ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter() throws Exception {
ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter();
filter.setAuthenticationManager(authenticationManager);
return filter;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
endpoints.authorizationCodeServices(verificationCodeService);
endpoints.tokenServices(tokenServices());
endpoints.reuseRefreshTokens(true);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()");
oauthServer.checkTokenAccess("permitAll()");
oauthServer.realm("myapp/client");
oauthServer.addTokenEndpointAuthenticationFilter(clientCredentialsTokenEndpointFilter());
oauthServer.allowFormAuthenticationForClients();
}
}
}
、ResourceServerの設定は、他の構成が重複しています。どうすれば修正できますか?私はどんな助けでも感謝しています。
こんにちは@sofiaguyang、アイデア来ていただきありがとうございます。私は 'ResourceServerConfiguration'と' SecurityConfig'の適用範囲を制限しました。今度は、「認証オブジェクトがSecurityContextに見つかりませんでした」というエラーは表示されません。しかし、私はログインボタンを紛失しました。私は自分のコードで何が問題なのか分かりません。 – Alex
一般的な流れは次のとおりです。OAuth2経由で保護されているエンドポイントにアクセスする場合、アクセストークンを提供する必要があります。そうしないと、許可されていない/禁止された応答が送信されます。アクセストークンは、/ oauth/authorizeから認証コードを取得し、認証コードを '/ oauth/token'のアクセストークンと交換することで得られます。最初に、ユーザが '/ oauth/authorize'にアクセスすると、ユーザはまだ認証されていません。しかし、認証するために認証する必要があるため、ログインページにリダイレクトされます。 – sofiaguyang
ありがとう!ログインボタンについて考えていますか?または、別の方法でResourceServerを構成する必要がありますか? antMatchers( "/ api/v0/**")。authenticated()。antMatchers( "/ api/v0/**")。これは私の設定です:http.requestMatcher(新しいAntPathRequestMatcher( " ** "))。denyAll(); ' – Alex