tutorial mkyong example español ejemplo java spring rest security oauth-2.0

java - mkyong - Spring OAUTH-diferente inicio de sesión para web e REST



spring security oauth2 rest example (2)

¿Has intentado agregar URL path /apilogin , al

.antMatchers("/", "/register", "/registrationConfirm",/resendRegistrationToken", "/park/**") .permitAll()

Supongo que la aplicación está redirigiendo el acceso / apilogin a la página de inicio de sesión de autenticación común, ya que no se agrega a la lista de acceso no autenticado.

Hola, tengo una aplicación web asegurada con seguridad Spring, con una página de inicio de sesión. Esta es mi configuración de seguridad

@Configuration @ComponentScan("it.besmart") @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ @Autowired @Qualifier("customUserDetailsService") UserDetailsService userDetailsService; @Autowired CustomSuccessHandler customSuccessHandler; @Autowired CustomAuthenticationFailureHandler customAuthenticationFailureHandler; @Autowired DataSource dataSource; @Autowired private ConnectionFactoryLocator connectionFactoryLocator; @Autowired private UsersConnectionRepository usersConnectionRepository; @Autowired private FacebookConnectionSignup facebookConnectionSignup; private final static Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class); @Autowired public void configureGlobalService(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } protected void configure(HttpSecurity http) throws Exception { logger.debug("Webapp security configured"); http. authorizeRequests() .antMatchers("/", "/register", "/registrationConfirm", "/resendRegistrationToken", "/park/**") .permitAll() .antMatchers("/edit/**", "/payment/**", "/plate/**", "/book/**", "/home", "/stop/**", "/notification/**", "/include/**") .access("hasRole(''USER'') or hasRole(''ADMIN'') or hasRole(''PARK'')").antMatchers("/admin/**") .access("hasRole(''ADMIN'') or hasRole(''PARK'')").antMatchers("/updatePassword") .hasAuthority("CHANGE_PASSWORD_PRIVILEGE") .and().formLogin().loginPage("/") .successHandler(customSuccessHandler).failureHandler(customAuthenticationFailureHandler) .usernameParameter("email").passwordParameter("password").and().rememberMe() .rememberMeParameter("remember-me").tokenRepository(persistentTokenRepository()) .tokenValiditySeconds(86400).and().exceptionHandling().accessDeniedPage("/Access_Denied").and() .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/?logout=true").permitAll(); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Bean public PersistentTokenRepository persistentTokenRepository() { JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl(); db.setDataSource(dataSource); return db; } }

Esto funciona bien asegurando toda mi aplicación web.

En la misma aplicación también tengo un servidor de recursos / autorización para proteger algunas API REST.

Algunos recursos están protegidos con una concesión de código de autorización, por lo que la aplicación móvil que no es de confianza debe tomar el token de acceso de mi aplicación con un formulario de inicio de sesión. Me gustaría que la aplicación utilice una página de inicio de sesión diferente al intentar iniciar sesión desde la aplicación móvil.

Esta es la configuración de mi resourceServer

@EnableResourceServer @ComponentScan("it.besmart.easyparking") @EnableGlobalMethodSecurity(prePostEnabled = true) public class ResourceServerConfig { private final Logger logger = LoggerFactory.getLogger(ResourceServerConfig.class); @Autowired DataSource dataSource; private static final String RESOURCE_ID = "easyparking_api"; @Configuration // @Order(2) public class grantCredentialsConfiguration extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { logger.debug("Api security configured"); http .requestMatchers().antMatchers("/api/oauth/**").and().authorizeRequests() .antMatchers("/api/oauth/**").access("hasRole(''USER'')").and().formLogin().loginPage("/apilogin") .permitAll(); } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.tokenStore(tokenStore()).resourceId(RESOURCE_ID); } } @Configuration // @Order(4) public class clientCredentialsConfiguration extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { logger.debug("Client security configured"); http .requestMatchers().antMatchers("/oauth2/**", "/api/registration", "/api/park/**").and() .authorizeRequests().antMatchers("/oauth2/**", "/api/registration", "/api/park/**").authenticated(); } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.tokenStore(tokenStore()).resourceId(RESOURCE_ID); } } @Bean public TokenStore tokenStore() { return new JdbcTokenStore(dataSource); } }

entonces, grantCredentialsConfiguration debe redirigir las solicitudes al formulario / apilogin, pero no es así, me redireccionan a la página principal de inicio de sesión de la aplicación web ... ¿Cómo se puede lograr?

EDITAR

Mirando más de cerca a los registros, parece que cuando trato de pulsar / oauth / authorize / la cadena de seguridad normal se lleva a cabo y obtengo

2017-05-25 12:23:15 DEBUG o.s.security.web.FilterChainProxy[310] - /oauth/authorize?response_type=token&client_id=test&redirect_uri=https://www.getpostman.com/oauth2/callback reached end of additional filter chain; proceeding with original chain 2017-05-25 12:23:15 DEBUG o.s.s.o.p.e.FrameworkEndpointHandlerMapping[310] - Looking up handler method for path /oauth/authorize 2017-05-25 12:23:15 DEBUG o.s.s.o.p.e.FrameworkEndpointHandlerMapping[317] - 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)] 2017-05-25 12:23:15 DEBUG o.s.s.w.a.ExceptionTranslationFilter[163] - 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.

Parece que buscar un controlador para gestionar la solicitud, en lugar de redireccionar a / api / apilogin, encuentra una Authentication exception y yo voy a la página de inicio de sesión estándar ... ¿Pero por qué me sale esta excepción?


Sucede porque no ha especificado el orden de las clases de configuración de seguridad.

En Spring, la protección de los recursos de seguridad se debe mencionar de específica a genérica.

Class SecurityConfiguration es más genérica que grantCredentialsConfiguration . Como ambos protegen los siguientes recursos.

  • SecurityConfiguration protege /** ( URL predeterminada )
  • grantCredentialsConfiguration /api/oauth/**

Como la orden no está definida, la configuración genérica de SecurityConfiguration oculta la configuración específica mediante grantCredentialsConfiguration

Para que funcionen como se espera, tendrás que definir el orden de la siguiente manera.

@Configuration @Order(2)//Generic config should have larger value (lower priority) public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ } @Configuration @Order(1)//Specific with lower value (higher priority) public class grantCredentialsConfiguration extends ResourceServerConfigurerAdapter { }

Nota: Dado que estas páginas de inicio de sesión no provienen de diferentes aplicaciones, comparten SecurityContextHolder o el contexto de seguridad. Por lo tanto, si inicia sesión desde una página de inicio de sesión y luego intenta acceder al recurso protegido de la otra, no será redirigido a la siguiente página de inicio de sesión. En cambio, obtendrá el 403 (dependiendo de los roles asignados por las diferentes páginas de inicio de sesión). En un momento, solo se puede mantener una sesión de inicio de sesión.

Aquí hay una muestra en Github

https://github.com/ConsciousObserver/TestMultipleLoginPages.git