Spring OAUTH - 针对web e REST的不同登录

bes*_*art 11 java security rest spring oauth-2.0

您好,我是一个使用Spring安全保护的Web应用程序,带有登录页面.这是我的安全配置

@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;
    }

}
Run Code Online (Sandbox Code Playgroud)

这可以通过保护我的所有Web应用程序来实现.

在同一个应用程序中,我还有一个资源/授权服务器来保护一些REST API.

某些资源受授权代码授权保护,因此不受信任的移动应用程序应使用登录表单从我的应用程序中获取访问令牌.我希望应用程序在尝试从移动应用程序登录时使用不同的登录页面.

这是我的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);
    }

}
Run Code Online (Sandbox Code Playgroud)

所以,grantCredentialsConfiguration应该将请求重定向到/ apilogin表单,但它没有,我被重定向到主Web应用程序登录页面...如何实现?

编辑

仔细观察日志,看起来当我尝试点击/ oauth/authorize /正常的安全链发生时,我得到了

    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.
Run Code Online (Sandbox Code Playgroud)

所以它看起来像是在寻找一个处理程序来管理请求,而不是根据需要重定向到/ api/apilogin,他找到了一个Authentication exception,所以我去标准的登录页面...但为什么我得到这个例外?

小智 0

您是否尝试过将 URL 路径添加/apilogin

.antMatchers("/",  "/register", "/registrationConfirm",/resendRegistrationToken", "/park/**")
.permitAll()
Run Code Online (Sandbox Code Playgroud)

我猜测应用程序正在将 /apilogin 访问重定向到通用身份验证登录页面,因为它没有添加到未经身份验证的访问列表中。