[SPRING] 사용자 지정 인증 공급자가 호출되지 않음
SPRING사용자 지정 인증 공급자가 호출되지 않음
나는 Spring Security로 고객 AuthenticationProvider를 설정하려고 노력하고 있지만 작동하는 데 많은 행운이 없다. XML 구성을 기반으로하는 학습 자료가 많기 때문에 Java 구성을 사용하고 있습니다.
이것은 Spring v4.0.1.RELEASE를 사용하지만 Spring Security v3.2.2.RELEASE를 사용합니다. 아마 버전 번호 충돌?
내가 말할 수있는 한, 내 공급자를 만드는 것 뿐이야.
public class KBServicesAuthProvider implements AuthenticationProvider {
@Autowired
private ApplicationConfig applicationConfig;
@Autowired
private SessionServiceClient sessionServiceClient;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String email = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
try {
KBSessionInfo sessionInfo = sessionServiceClient.login(applicationConfig.getKbServicesPresenceId(), email,
password);
List<GrantedAuthority> grantedRoles = new ArrayList<>();
for (KBRoleMembership role : sessionInfo.getAuthenticatedUser().getRoleMemberships()) {
grantedRoles.add(new SimpleGrantedAuthority(role.getRoleId()));
}
return new UsernamePasswordAuthenticationToken(email, password, grantedRoles);
} catch (InvalidSessionException e) {
throw new AuthenticationCredentialsNotFoundException("Username or password was not accepted", e);
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
그런 다음 내 보안 설정을 설명하는 클래스를 설정하십시오. 이 클래스는 내 제공자와 연결됩니다.
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired(required = true)
SessionServiceClient sessionServiceClient;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated();
http.formLogin().loginPage("/login").permitAll().and().logout().permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(getKBServicesAuthenticationProvider());
}
@Bean
protected AuthenticationProvider getKBServicesAuthenticationProvider() {
return new KBServicesAuthProvider();
}
}
하지만 로그에서 아무 것도 볼 수없고 내 디버그 지점 중 하나도 공격을 받고 있지 않습니다. 응용 프로그램은 안전하지 않은 역할을합니다 (그래서 다양한 URL에 도달 할 수 있습니다).
내가 무엇을 확인해야하는지에 대한 아이디어가 있습니까?
해결법
-
==============================
1.이것은 내가 완전히 이걸 고민하고 있기 때문에 완전한 대답이 아닐 수도 있습니다. 사용자 지정 인증 공급자와 사용자 지정 사용자 세부 정보 서비스를 사용하고 있습니다. 내 사용자 세부 정보 서비스에서 중단 점에 도달하지만 내 인증 공급자에서는 중단되지 않습니다. 다음은 내 전체 config 클래스의 모습입니다.
이것은 내가 완전히 이걸 고민하고 있기 때문에 완전한 대답이 아닐 수도 있습니다. 사용자 지정 인증 공급자와 사용자 지정 사용자 세부 정보 서비스를 사용하고 있습니다. 내 사용자 세부 정보 서비스에서 중단 점에 도달하지만 내 인증 공급자에서는 중단되지 않습니다. 다음은 내 전체 config 클래스의 모습입니다.
@Configuration @EnableWebMvcSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService userDetailsService; @Autowired private CustomAuthenticationProvider customAuthenticationProvider; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { AuthenticationProvider rememberMeAuthenticationProvider = rememberMeAuthenticationProvider(); TokenBasedRememberMeServices tokenBasedRememberMeServices = tokenBasedRememberMeServices(); List<AuthenticationProvider> authenticationProviders = new ArrayList<AuthenticationProvider>(2); authenticationProviders.add(rememberMeAuthenticationProvider); authenticationProviders.add(customAuthenticationProvider); AuthenticationManager authenticationManager = authenticationManager(authenticationProviders); http .csrf().disable() .headers().disable() .addFilter(new RememberMeAuthenticationFilter(authenticationManager, tokenBasedRememberMeServices)) .rememberMe().rememberMeServices(tokenBasedRememberMeServices) .and() .authorizeRequests() .antMatchers("/js/**", "/css/**", "/img/**", "/login", "/processLogin").permitAll() .antMatchers("/index.jsp", "/index.html", "/index").hasRole("USER") .antMatchers("/admin", "/admin.html", "/admin.jsp", "/js/saic/jswe/admin/**").hasRole("ADMIN") .and() .formLogin().loginProcessingUrl("/processLogin").loginPage("/login").usernameParameter("username").passwordParameter("password").permitAll() .and() .exceptionHandling().accessDeniedPage("/login") .and() .logout().permitAll(); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/js/**", "/css/**", "/img/**"); } @Bean public BCryptPasswordEncoder bCryptPasswordEncoder(){ return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(List<AuthenticationProvider> authenticationProviders) { return new ProviderManager(authenticationProviders); } @Bean public TokenBasedRememberMeServices tokenBasedRememberMeServices() { return new TokenBasedRememberMeServices("testKey", userDetailsService); } @Bean public AuthenticationProvider rememberMeAuthenticationProvider() { return new org.springframework.security.authentication.RememberMeAuthenticationProvider("testKey"); } protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); } }
나는 방금 HttpSecurity 객체에 인증 공급자를 추가하면 내 중단 점에 충돌이 발생한다는 것을 발견했습니다.
http .csrf().disable() .headers().disable() .authenticationProvider(customAuthenticationProvider)
내 목표는이 구성으로하지 않는 BCryptPasswordEncoder를 작동시키는 것입니다. 모든 것이 잘못된 자격 증명으로 반환됩니다. 어쨌든, 그냥 나눌 줄 알았어.
-
==============================
2.나는 똑같은 문제에 직면했다. 문제는 항상 false를 리턴 할 당신의 방법에있다.
나는 똑같은 문제에 직면했다. 문제는 항상 false를 리턴 할 당신의 방법에있다.
@Override public boolean supports(Class<?> authentication) { return authentication.equals (UsernamePasswordAuthenticationToken.class); }
위의 방법을 아래의 방법으로 변경하면 문제가 해결됩니다.
@Override public boolean supports(Class<?> authentication) { return (UsernamePasswordAuthenticationToken.class .isAssignableFrom(authentication)); }
-
==============================
3.@Autowired 주석을 잊어 버렸습니다.
@Autowired 주석을 잊어 버렸습니다.
@Autowired @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(getKBServicesAuthenticationProvider()); }
또한 .antMatchers ( "/"). permitAll ()을 제거 할 수 있습니다.
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated(); http.formLogin().loginPage("/login").permitAll().and().logout().permitAll(); }
-
==============================
4.Spring Security가 Tomcat에서 작동하는 이유를 읽은 후에 springSecurityFilterChain을 도입하여 동일한 문제 (내 맞춤형 인증 공급자가 공격받지 못함)를 해결하고이 문제를 해결했지만 Weblogic에 배포 할 때가 아닙니다. 그래서 문제는 아마 WebServer와 관련이 있을지 모르지만 Tomcat에서도 맞춤형 인증 제공자 문제를 겪었고 이제 Tomcat에서 내 구성이 작동하는지 확인했습니다.
Spring Security가 Tomcat에서 작동하는 이유를 읽은 후에 springSecurityFilterChain을 도입하여 동일한 문제 (내 맞춤형 인증 공급자가 공격받지 못함)를 해결하고이 문제를 해결했지만 Weblogic에 배포 할 때가 아닙니다. 그래서 문제는 아마 WebServer와 관련이 있을지 모르지만 Tomcat에서도 맞춤형 인증 제공자 문제를 겪었고 이제 Tomcat에서 내 구성이 작동하는지 확인했습니다.
나는 Spring 4.3.3과 Spring Security 4.1.3을 포함하고 전통적인 배치를 따르는 Spring boot 1.4.1 버전을 사용하고있다.
Tomcat v9.0 및 WebLogic 12c R2에 대한 구성을 테스트하고이 구성이 모두 작동하는지 확인했습니다. 적어도 Tomcat을 사용하는 누군가에게 도움이되기를 바랍니다.
아래는 메인 클래스에서 시작된 구성입니다.
Application.java
public class Application { public static void main( String[] args ) { SpringApplication.run(new Class[] {AppConfig.class, Initializer.class, SecurityInitializer.class}, args); } }
Initializer.java
public class Initializer extends SpringBootServletInitializer implements WebApplicationInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(AppConfig.class); } @Override public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(AppConfig.class); // Manage the lifecycle of the root application context container.addListener(new ContextLoaderListener(rootContext)); // Create the dispatcher servlet's Spring application context AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext(); dispatcherContext.register(WebConfig.class); // Register and map the dispatcher servlet ServletRegistration.Dynamic dispatcher = container.addServlet("my-servlet", new DispatcherServlet(dispatcherContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/*"); } }
여기서 AbstractSecurityWebApplicationInitializer는 onStartup 메소드에서 springSecurityFilterChain을 빌드합니다. 기본 구성을 사용하려고하므로 아무 것도 구현하지 않았습니다.
SecurityInitializer.java
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer { }
AppConfig.java
@Configuration @EnableAutoConfiguration @EnableScheduling @EnableMBeanExport @EnableAsync @EnableAspectJAutoProxy @ComponentScan("com.my.package") public class AppConfig { }
SecurityConfig.java
@Configuration @EnableWebSecurity @ComponentScan("com.my.package") public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private RestfulRemoteAuthenticationProvider restfulRemoteAuthenticationProvider; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(restfulRemoteAuthenticationProvider); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); } }
WebConfig.java
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.my.controller.package") public class WebConfig extends WebMvcConfigurerAdapter { @Bean public InternalResourceViewResolver internalViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp"); viewResolver.setOrder(1); return viewResolver; } }
이것은 안정적인 요청을 통해 다른 구성 요소에서 인증 정보를 가져 오는 내 사용자 지정 인증 공급자입니다.
RestfulRemoteAuthenticationProvider.java
@Component public class RestfulRemoteAuthenticationProvider implements AuthenticationProvider { @Autowired private ManagementClientAdapterFactory managementClientAdapterFactory; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String username = authentication.getName(); String password = authentication.getCredentials().toString(); // my logic to get and configure authSource which is my environment specific thing, also same for RemoteAuthRequestResult RemoteAuthRequestResult result = (RemoteAuthRequestResult)authSource.sendRequest(); if(result.isAuthenticated()) { List<GrantedAuthority> grantedAuths = new ArrayList<>(); grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); return new UsernamePasswordAuthenticationToken(username, password, grantedAuths); } throw new BadCredentialsException("User not found by given credential"); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } }
-
==============================
5.
Something like should be present in java config @Configuration @EnableGlobalMethodSecurity(prePostEnabled=true) public class HelloMethodSecurityConfig { }
-
==============================
6.@EnableWebMvcSecurity는 4.0 https://jira.spring.io/browse/SEC-2790에서 더 이상 사용되지 않습니다.
@EnableWebMvcSecurity는 4.0 https://jira.spring.io/browse/SEC-2790에서 더 이상 사용되지 않습니다.
구성을 다시 고려할 수도 있습니다.
-
==============================
7.
<security:global-method-security pre-post-annotations="enabled"/>
from https://stackoverflow.com/questions/22453550/custom-authentication-provider-not-being-called by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] ng-file-upload를 사용하여 Spring에서 많은 파일을 업로드하려고 할 때 빈 목록 <MultipartFile> (0) | 2019.03.15 |
---|---|
[SPRING] 다중 임차가있는 스프링 부트 + 스프링 데이터 (0) | 2019.03.15 |
[SPRING] 문자 인코딩 문제 스프링 (0) | 2019.03.15 |
[SPRING] 스프링 부트 유효성 검사 메시지가 해결되지 않습니다. (0) | 2019.03.14 |
[SPRING] Spring mvc 모호한 매핑이 발견되었습니다. 컨트롤러 bean 메소드를 맵핑 할 수 없습니다. (0) | 2019.03.14 |