#java #authentication #exception #oauth-2.0 #spring-restcontroller
#java #аутентификация #исключение #oauth-2.0 #spring-restcontroller
Вопрос:
Я не могу сгенерировать пользовательское сообщение с помощью RestControllerAdvice для сбоя аутентификации OAuth2.
Сервер ресурсов :
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{
public ResourceServerConfiguration() {
System.out.println("ResourceServerConfiguration : constructor");
}
private static final String RESOURCE_ID = "my_rest_api";
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
System.out.println("ResourceServerConfiguration : configure with requested resources");
resources.resourceId(RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
System.out.println("ResourceServerConfiguration : configure with requested http request");
http.
anonymous().disable()
.requestMatchers().antMatchers("/login/**")
.and().authorizeRequests()
.antMatchers("/login/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
Сервер авторизации :
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter{
public AuthorizationServerConfiguration() {
System.out.println("Inside AuthorizationServerConfiguration");
}
/*class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer
* which provides all the necessary methods to configure an Authorization server.*/
private static String REALM = "MY_OAUTH_REALM";
@Autowired
private TokenStore tokenStore;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
System.out.println("AuthorizationServerConfiguration configure for security");
security.realm(REALM "/client");
}
//configures authorization using password authentication
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
System.out.println("AuthorizationServerConfiguration configure for clients");
clients.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password","authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT")
.scopes("read","write","trust")
.secret("secret")
.accessTokenValiditySeconds(120) //Access token is only valid 2 min.
.refreshTokenValiditySeconds(600);// refresh token is valid for 10 mins.
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
System.out.println("AuthorizationServerConfiguration configure for endpoints");
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler).authenticationManager(authenticationManager);
}
}
Веб-безопасность :
@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
public OAuth2SecurityConfiguration() {
System.out.println("OAuth2SecurityConfiguration : constructor");
}
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception{
System.out.println("OAuth2SecurityConfiguration : Set global users");
auth.inMemoryAuthentication()
.withUser("abc").password("abc@123").roles("ADMIN");
System.out.println("Auth :" auth);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
System.out.println("OAuth2SecurityConfiguration : authenticationManagerBean");
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("OAuth2SecurityConfiguration : path set as /oauth/token");
http
.sessionManagement()
.and()
.cors()
.and()
.csrf().disable()
.anonymous().disable()
.authorizeRequests().antMatchers("/oauth/token").permitAll()
.and()
.formLogin().disable()
.httpBasic().disable()
.logout().disable();
}
@Bean
public TokenStore tokenStore() {
System.out.println("OAuth2SecurityConfiguration : tokenStore");
return new InMemoryTokenStore();
}
@Override
public void configure( WebSecurity web ) throws Exception
{
web.ignoring().antMatchers( HttpMethod.OPTIONS, "/**" );
}
@Bean
@Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
System.out.println("OAuth2SecurityConfiguration : get user approval handler for requested tokenStore");
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
System.out.println("OAuth2SecurityConfiguration : create approval store for requested tokenStore");
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
RestControllerAdvice
@RestControllerAdvice
public class RestErrorHandler {
@ExceptionHandler({AuthenticationException.class})
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ResponseBody
public ResponseEntity<String> handleAuthenticationException(AuthenticationException ex) {
return ErrHandler.getInstance().getErrResp(ErrorMsg.AUTH_EXCEPTION.getErrCd(), ErrorMsg.AUTH_EXCEPTION.getErrMsg());
}
@ExceptionHandler({HttpMessageNotReadableException.class,BadCredentialsException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ResponseEntity<String> badRequestException(HttpMessageNotReadableException ex) {
return ErrHandler.getInstance().getErrResp(ErrorMsg.BAD_REQ_EXCEPTION.getErrCd(), ErrorMsg.BAD_REQ_EXCEPTION.getErrMsg());
}
}
При доступе к URL-адресу без аутентификации сервер выдает исключение, а не сообщение. Каково наилучшее решение этой проблемы.
Ответ №1:
Попробуйте что-то вроде этого,
@ApiOperation(authorizations = {
@Authorization(value = "oauth") }, value = "Method does some function", response = String.class)
При первом попадании попробуйте авторизоваться с помощью OAuth, в случае сбоя это выдаст сообщение об ошибке аутентификации.
Комментарии:
1. ApiOperation из библиотеки аннотаций swagger Есть ли какой-либо способ, которым я могу работать без использования этой библиотеки.