Я хочу реализовать следующий сценарий с пружинной безопасностью.
СЦЕНАРИЙ:
В моем приложении есть пользовательская модель, которая имеет роль «ROLE_USER». Теперь я хочу предложить логин моей заявке с и без формы. Когда пользователь входит в систему через браузер, должна появиться форма. Когда попытка входа в систему происходит из мобильного приложения, я просто хочу использовать базовую аутентификацию. После успешного входа в систему пользователь получает добавленную временную роль (ROLE_WEB или ROLE_MOBILE) для дальнейших процессов аутентификации.
РЕШИТЬ:
Полагаю, это не идеальное решение, когда я устанавливаю бот-антматчеров на "/ **", все работает как шарм. Я думаю, что заголовок проверяется, если учетные данные установлены. Если true, мобильный доступ используется, если не веб-доступ.
Пожалуйста, поправьте меня и улучшите мое решение, если это плохая практика
РЕАЛИЗАЦИЯ:
Я не уверен в лучшей практике, поэтому поправьте меня, если я ошибаюсь.
Я создал две разные конечные точки: / login и / login / mobile.
Моя конфигурация безопасности следующая.
@Configuration
@EnableWebSecurity
@Order(1)
public class MobileSecurityAdapter extends WebSecurityConfigurerAdapter{
@Autowired
private AuthenticationEntryPoint entryPoint;
@Autowired
private MyUserDetailsService userDetailsService;
@Bean
@Override
@Qualifier("authenticationManagerBean")
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/login/mobile").permitAll().anyRequest().authenticated().and().httpBasic()
.authenticationEntryPoint(entryPoint);
http.addFilterAt(new CustomBasicAuthenticationFilter(authenticationManagerBean()),
BasicAuthenticationFilter.class);
}
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
}
@Configuration
@EnableWebSecurity
@Order(2)
public class WebSecurityAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationEntryPoint entryPoint;
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
AuthenticationManager authenticationManagerBean;
// @Bean
// @Override
// @Qualifier("authenticationManagerBean")
// public AuthenticationManager authenticationManagerBean() throws Exception {
// return super.authenticationManagerBean();
// }
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/login").permitAll().anyRequest().authenticated().and().httpBasic()
.authenticationEntryPoint(entryPoint);
http.addFilterAt(new CustomBasicAuthenticationFilter(authenticationManagerBean),
BasicAuthenticationFilter.class);
http.formLogin().loginPage("/login").successHandler(new RoleBasedAuthenticationSuccessHandler());
http.formLogin().failureUrl("/login");
http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.invalidateHttpSession(true).deleteCookies("SESSION");
}
}
Проблема в том, что теперь каждый раз, когда я звоню / входю в систему, я получаю стандартную форму для входа в систему, и после входа в систему запрашивается моя пользовательская форма входа. Когда я звоню / user / login почтальоном, чтобы имитировать мобильное устройство, все работает нормально. Мой успешный обратный вызов вызван, и я могу перенаправить.
ВОПРОС:
Я хочу разделить возможности входа в систему, которые я могу вызвать по конечной точке, поэтому я предполагаю, что мои antMatchers ошибаются. Что мне нужно изменить в моей конфигурации, чтобы я мог предоставить один логин и один без формы.
EDIT:
Я только что изменил порядок двух адаптеров безопасности, и теперь мой веб-логин работает так, как я хочу, и получаю обработчик Rolebasedauth.auccesshandler. Здесь я могу перенаправить на свой URL. Но теперь у меня возникла проблема с моим мобильным логином. Я также могу успешно войти в систему, но когда я хочу перенаправить URL в мой CusomBasicAuthFilter, я получаю следующую ошибку:
{
«метка времени»: «2019-05-22T13: 28: 04.780 + 0000»,
«статус»: 500,
«ошибка»: «Внутренняя ошибка сервера»,
"message": "Невозможно вызвать sendError () после подтверждения ответа",
«trace»: «java.lang.IllegalStateException: невозможно вызвать sendError () после того, как ответ был зафиксирован \ r \ n \ tat
org.apache.catalina.connector.ResponseFacade.sendError (ResponseFacade.java:472) \ г \ п \ тат
javax.servlet.http.HttpServletResponseWrapper.sendError (HttpServletResponseWrapper.java:129) \ г \ п \ тат
org.springframework.session.web.http.OnCommittedResponseWrapper.sendError (OnCommittedResponseWrapper.java:106) \ г \ п \ тат
javax.servlet.http.HttpServletResponseWrapper.sendError (HttpServletResponseWrapper.java:129) \ г \ п \ тат
javax.servlet.http.HttpServletResponseWrapper.sendError (HttpServletResponseWrapper.java:129) \ г \ п \ тат
org.springframework.security.web.util.OnCommittedResponseWrapper.sendError (OnCommittedResponseWrapper.java:109) \ г \ п \ тат
javax.servlet.http.HttpServletResponseWrapper.sendError (HttpServletResponseWrapper.java:129) \ г \ п \ тат
org.springframework.security.web.util.OnCommittedResponseWrapper.sendError (OnCommittedResponseWrapper.java:109) \ г \ п \ тат
org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest (ResourceHttpRequestHandler.java:454) \ г \ п \ тат
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle (HttpRequestHandlerAdapter.java:53) \ г \ п \ тат
org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:1038) \ г \ п \ тат
org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:942) \ г \ п \ тат
org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:998) \ г \ п \ тат
org.springframework.web.servlet.FrameworkServlet.doGet (FrameworkServlet.java:890) \ г \ п \ тат
javax.servlet.http.HttpServlet.service (HttpServlet.java:634) \ г \ п \ татorg.springframework.web.servlet.FrameworkServlet.service (FrameworkServlet.java:875) \ r \ n \ tat javax.servlet.http.HttpServlet.service (HttpServlet.java:741) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:231) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat.cat.websocket.server.WsFilter.doFilter (WsFilter.java:53) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal (BasicAuthenticationFilter.java:2ra \me.spr.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) \ r \ n \ tat org.che.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal (HttpTraceFilter.jter \ nava)\ tat org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterCha3 \ r) \ n \ r: \org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:j::)org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke (FilterSecurityInterceptor.java:127) \ r \ n \ tat org.springframework.security.web.access.intercept.FilterSecurityInterceptor.dojilter (Filter) ()\ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) \ r \ n \ tat org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter.java:119) \ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChain \ r4 \ r4) \ Filter \ Chain.doFilterorg.springframework.security.web.session.SessionManagementFilter.doFilter (SessionManagementFilter.java:137) \ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter \ Filter_java.NF:\ tat org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter (AnonymousAuthenticationFilter.java:111) \ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.hain.hain.hain:\ n \ tat org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter (SecurityContextHolderAwareRequestFilter.java:170) \ r \ n \ tat org.springframework.security.web.Filin\ r \ n \ tat org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter (RequestCacheAwareFilter.java:63) \ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain..web.authentication.www.BasicAuthenticationFilter.doFilterInternal (BasicAuthenticationFilter.java:215) \ r \ n \ tat org.springframework.web.filter..security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) \ r \ n \ tat org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal (BasicAutheavaF2 \ n).tat org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) \ r \ n \ tatorg.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) \ r \ n \ tat org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilper\ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) \ r \ n \ tat org.springframework.security.web.authentication.logout.LogoutFilter.doFilter.jav (Log)\ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) \ r \ n \ tat org.springframework.security.web.header.HeaderWriterFilter.ilFterWerter (66) \ r \ n \ tat org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) \ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.Chain.Chain.334) \ r \ n \ tat org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter (SecurityContextPersistenceFilter.java:105) \ r \ n \ tat org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) \ r \ n \ tat org.springframeb.secte.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal (WebAsyncManagerIntegrationFilter.java:56) \ r \ n \ tat org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter \ nwork \ r.web.FilterChainProxy $ VirtualFilterChain.doFilter (FilterChainProxy.java:334) \ r \ n \ tat org.springframework.security.web.FilterChainProxy.doFilterInternal (FilterChainProxy.java:215) \ r \ nsecf. или.web.FilterChainProxy.doFilter (FilterChainProxy.java:178) \ r \ n \ tat org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:357) \ r \ n \ tat org.springfrawork.DelegatingFilterProxy.doFilter (DelegatingFilterProxy.java:270) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat org.springframework.web.filter.Reiltern.FilterFontRequestContextFilter.java:99)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterFilterChater.Java: 193) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat org.springframework.web.filter.FormContentFilter.doFilterInternal (FormContentFilter.92) \ r \ n \ tat org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter3: ApplicationFilter: ApplicationFilter:\ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal (HiddenHttpMethodFilter.java:93) \ r \ n \ tat org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:10il.internalDoFilter (ApplicationFilterChain.java:193) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat org.springframework.session.web.http.Session.doFilterInternal (SessionRepositoryFilter.java:147) \ r \ n \ tat org.springframework.session.web.http.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:81) \ r \ n \ tat org.apache.catalinaFore.internalDoFilter (ApplicationFilterChain.java:193) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tatorg.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics (WebMvcMetricsFilter.java:154) \ r \ n \ tat org.springframework.boot.actuate.metrics.Java: 122) \ r \ n \ tat org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal (WebMvcMetricsFilter.java:107) \ r \ n \ tat org.springframework.web.filqu.doFilter (OncePerRequestFilter.java:107) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) \ r \ n \ tat org.apache.catalina.core.AppinFilterCilterFilterApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:200) \ r \ n \ tat org.springframeworkest.web.filter.ilfFilterReReFJava: 107) \ r \ n \ tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) \ r \ n \ tat org.apache.catalina.core.StandardWrapperValve.invoke (стандартная упаковка)Java: 199) \ r \ n \ tat org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:96) \ r \ n \ tat org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:490) \ r \ n \ tat org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:139) \ r \ n \ tat org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:92)\ r \ n \ tat org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:74) \ r \ n \ tat org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:343) \ r\ n \ tat org.apache.coyote.http11.Http11Processor.service (Http11Processor.java:408) \ r \ n \ tat org.apache.coyote.AbstractProcessorLight.process (AbstractProcessorLight.java:66) \ r \ n \ tatorg.apache.coyote.AbstractProtocol $ ConnectionHandler.process (AbstractProtocol.java:770) \r \ n \ tat org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun (NioEndpoint.java:1415) \ r \ n \ tat org.apache.tomcat.util.net.SocketProcessorBase.run (SocketProcessorBase.java: 49) \ r \ n \ tat java.util.concurrent.ThreadPoolExecutor.runWorker (неизвестный источник) \ r \ n \ tat java.util.concurrent.ThreadPoolExecutor $ Worker.run (неизвестный источник) \ r \ n \ tat org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run (TaskThread.java:61) \ r \ n \ tat java.lang.Thread.run (неизвестный источник) \ r \ n "," путь ":" /login / mobile "}
Итак, я думаю, что запрос изменился из-за изменения в заказе, и из-за этого я не могу перенаправить / переслать запрос.Есть ли способ решить эту проблему?Вот мой обработчик:
@Component
@Qualifier("customBasicAuthFilter")
public class CustomBasicAuthenticationFilter extends BasicAuthenticationFilter {
@Autowired
public CustomBasicAuthenticationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
protected void onSuccessfulAuthentication(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response, Authentication authResult) throws IOException {
Iterator<? extends GrantedAuthority> it = authResult.getAuthorities().iterator();
switch (it.next().getAuthority()) {
case (MyConstants.ROLE_USER): {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities());
updatedAuthorities.add(new SimpleGrantedAuthority("ROLE_MOBILE"));
Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(),
updatedAuthorities);
SecurityContextHolder.getContext().setAuthentication(newAuth);
response.sendRedirect("/route/user/mobile");
break;
}
default:
throw new AccessDeniedException("Not Allowed");
}
}
}