У меня есть API, который я хочу защитить с помощью OAuth2. Я уже сделал фиктивный тест с паролем grant_type, и все работает. Я могу запросить маркеры, получить доступ к защищенным конечным точкам и т. Д. Сервер действует как сервер авторизации и ресурсов.OAuth2 с защитой неявного клиента и csrf
Позже я прочитал, что должен использовать неявный тип grant_type, поскольку клиент будет javascript-приложением.
Мой клиент настроен так:
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {// @formatter:off
clients
.inMemory().withClient("web")
.redirectUris("http://localhost:3000")
.secret("secret")
.authorizedGrantTypes("implicit", "refresh_token").scopes("read", "write")
.accessTokenValiditySeconds(3600).refreshTokenValiditySeconds(2592000);
}
Если я пытаюсь получить доступ к конечной точке, как это: http://localhost:8080/oauth/authorize?grant_type=implicit&client_id=web&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3A3000
Я получаю это:
{
"timestamp": 1464136960414,
"status": 403,
"error": "Forbidden",
"message": "Expected CSRF token not found. Has your session expired?",
"path": "/oauth/authorize"
}
Как я могу иметь CSRF если это первый раз, когда я вызываю API? Если (только для тестирования) отключить CSRF, то я получаю это:
{
"timestamp": 1464136840865,
"status": 403,
"error": "Forbidden",
"exception": "org.springframework.security.authentication.InsufficientAuthenticationException",
"message": "Access Denied",
"path": "/oauth/authorize"
}
Настройка клиента с паролем grant_type я могу сделать этот вызов и все работает: http://localhost:8080/oauth/token?grant_type=password&username=test&password=123 А добавив Основной заголовок авторизации с идентификатором/секретом клиента.
Чтобы уточнить, идея состоит в том, чтобы иметь этот уникальный доверенный клиент. Таким образом, пользователь должен просто вводить логин/пароль, не запрашивая у пользователя права доступа к приложению.
Извините, если это глупый вопрос. Я читаю все, что могу найти, но не могу добиться успеха.
Спасибо!
EDIT:
My Spring Security Config:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MongoDBAuthenticationProvider authenticationProvider;
@Autowired
public void globalUserDetails(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Мой OAuth Config:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory().withClient("web")
.redirectUris("http://localhost:3000")
.secret("secret")
.authorizedGrantTypes("implicit", "refresh_token").scopes("read", "write")
.accessTokenValiditySeconds(3600).refreshTokenValiditySeconds(2592000);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
}
исключений в сервере:
2016-05-25 19:52:20.744 DEBUG 34968 --- [nio-8080-exec-5] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/authorize
2016-05-25 19:52:20.744 DEBUG 34968 --- [nio-8080-exec-5] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)]
2016-05-25 19:52:20.746 DEBUG 34968 --- [nio-8080-exec-5] o.s.s.w.a.ExceptionTranslationFilter : Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.InsufficientAuthenticationException: User must be authenticated with Spring Security before authorization can be completed.
at org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(AuthorizationEndpoint.java:138) ~[spring-security-oauth2-2.0.9.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
....
Спасибо за ваш ответ @Soma. Я слышал о «государственном» параметре, но до сих пор не обработал его, что касается моего дела. Я изменил его, но я все еще получаю ошибки. Я выпустил его как POST, и я получаю ошибку csrf, с GET я получаю Access Denied. Я обновлю свой вопрос еще одним кодом и посмотрю, сможете ли вы обнаружить какие-либо ошибки.Большое спасибо! – user1294431
Запрос должен быть GET. Просто чтобы подтвердить, вы зарегистрировали клиента? Отправьте подробное сообщение об ошибке с GET. Спасибо –
Я отредактировал ответ. Большое вам спасибо за вашу помощь и время. – user1294431