пишу 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
.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть jsp страница, которая показывает несколько квестовКаждый можно посмотреть и прокомментировать
Есть объект, и есть view для этого объектаЕсть Map<String, List<MyObject>>
Мне необходимо из одного класса получить картинку из другого класса, а именно из другого layout, относящегося ко второму классу
Я хочу сделать следующее приложение: Есть 2 конечные токи API: 1) /hello/user - возвращает строку Hello ${username}, где username имя пользователя 2) /hello/anonymous - возвращает...