пишу REST Api сервер, хочу добавить авторизацию. Для теста добавил следующие ресурсы
GET /api/test/getting, который возвращает privet всем без авторизацииGET /api/test/secret, который возвращает SECREEEET только авторизованым пользователем.Сейчас Spring Security настраивается следующим образом:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery(
"select username,password, enabled from users where username=?")
.authoritiesByUsernameQuery(
"select username, role from user_roles where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/test/getting").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(new Http401UnauthorizedEntryPoint())
.and()
.formLogin()
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling();
}
Через браузер и curl, первый ресурс выдает всем privet. А при попытке обратится ко второму через браузер перекидывает на форму логина, а потом отправляет POST /login с параметрами username=XXX&password=XXX&submit=Login, после чего в запросы добавляются куки. Я попробовал повторить такое поведение через curl с сохранением куки в файл, но меня сразу выкидывает с ошибкой 403.
Хочу узнать, как явно задать настройки логина, задание куков и убрать эту перессылку на логин, чтобы кидало ошибку 401.
Заранее спасибо за ответ.
Отлуп неавторизованных запросов с кодом ошибки в xml-конфигурации делается так
<beans:bean id="authEntryPoint"
class="org.springframework.security.web.authentication.HttpStatusEntryPoint">
<constructor-arg name="httpStatus"
value="#{T(org.springframework.http.HttpStatus).UNAUTHORIZED}" />
</beans:bean>
<security:http use-expressions="true" request-matcher="regex" entry-point-ref="authEntryPoint">
<security:intercept-url pattern="/api/test/getting" access="permitAll" />
<security:intercept-url pattern="/api/.*" access="isAuthenticated()" />
</security:http>
Правда, я бы лучше использовал org.springframework.security.web.authentication.Http403ForbiddenEntryPoint.
И для API лучше подойдёт аутентификация не через форму и куки, а передачей в заголовках jwt-токена или basic-credentials.
Как всегда пришлось решать все самим, напишу сам ответ, вдруг кому пригодится.
Решилась эта проблема на самом деле очень просто, необходимо было реализовать свой authenticationEntryPoint.
Итоговый код конфигурационного класса наследуемого от WebSecurityConfigurerAdapter.
@Autowired
private DataSource dataSource;
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery(
"select username,password, enabled from users where username=?")
.authoritiesByUsernameQuery(
"select username, role from user_roles where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/test/getting").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
И вот сам код AuthenticationEntryPoint, который наследуется от BasicAuthenticationEntryPoint.
@Override
public void commence
(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException {
response.addHeader("WWW-Authenticate", "Basic realm='" + getRealmName() + "'");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401 - " + authEx.getMessage());
}
@Override
public void afterPropertiesSet() throws Exception {
setRealmName("Watch Counter");
super.afterPropertiesSet();
}
В итоге открыт доступ без авторизации к /api/test/getting, но ко всему остальному нужна авторизация и без нее возвращается ошибка 401 с сообщением HTTP Status 401 - Full authentication is required to access this resource.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости