Spring security oauth2和表单登录配置

max*_*sap 19 spring spring-security oauth-2.0 spring-java-config

我的项目包括两个不同的部分,一个JSF管理面板和一个RESTfull服务.我正在尝试设置spring security以使用不同的身份验证方法,具体取决于用户导航的URL.

要求是

  • 导航到JSF页面的用户获得一个登录屏幕,他们使用表单身份验证进行身份验证.
  • 导航到REST服务的用户使用OAuth2隐式身份验证和基本身份验证进行令牌授予.

单独的配置单独工作,问题是当我尝试在一个配置中组合它们时,在这种情况下,似乎REST提供程序阻碍并验证每个请求,即使请求转到管理URL(这从春季安全订购中记录).

我的示例配置如下所示:

  • 对于表单登录(JSF)

    @Override
    @Order(1)
    protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/resources/**").permitAll()
            .antMatchers("/templates/**").permitAll()
            .antMatchers("/401.html").permitAll()
            .antMatchers("/404.html").permitAll()
            .antMatchers("/500.html").permitAll()
            .antMatchers("/api/**").permitAll()
            .antMatchers("/ui/admin.xhtml").hasAnyAuthority("admin", "ADMIN")
            .antMatchers("/thymeleaf").hasAnyAuthority("admin", "ADMIN")
            //.anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/ui/index.xhtml")
            .failureUrl("/login?error=1")
            .permitAll()
            .and()
            .logout()
            .permitAll()
            .and()
            .rememberMe()
            .and().exceptionHandling().accessDeniedPage("/error/403");
    
    Run Code Online (Sandbox Code Playgroud)
  • OAuth2安全配置(REST)

    @EnableResourceServer
    @Order(2)
    public class RestSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Inject
        private UserRepository userRepository;
    
        @Inject
        private PasswordEncoder passwordEncoder;
    
        @Bean
        ApplicationListener<AbstractAuthorizationEvent> loggerBean() {
            return new AuthenticationLoggerListener();
        }
    
        @Bean
        AccessDeniedHandler accessDeniedHandler() {
            return new AccessDeniedExceptionHandler();
        }
    
        @Bean
        AuthenticationEntryPoint entryPointBean() {
            return new UnauthorizedEntryPoint();
        }
    
        /*Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring()
                    .antMatchers(
                            "/resources/**"
                            , "/templates/**"
                            , "/login"
                            , "/logout"
                            , "/ui/**"
                            , "/401.html"
                            , "/404.html"
                            , "/500.html"
                    );
        }*/
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);
            if (contentNegotiationStrategy == null) {
                contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
            }
            MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
                    MediaType.APPLICATION_FORM_URLENCODED,
                    MediaType.APPLICATION_JSON,
                    MediaType.MULTIPART_FORM_DATA);
    
            http.authorizeRequests()
                    .antMatchers("/ui/**").permitAll()
                    .and()
                    .anonymous().disable()
                    .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and().httpBasic()
                    .and()
                    .exceptionHandling()
                    .accessDeniedHandler(accessDeniedHandler()) // handle access denied in general (for example comming from @PreAuthorization
                    .authenticationEntryPoint(entryPointBean()) // handle authentication exceptions for unauthorized calls.
                    .defaultAuthenticationEntryPointFor(entryPointBean(), preferredMatcher)
                    .and()
                    .authorizeRequests()
                    .antMatchers("/api/**").fullyAuthenticated();
    
        }
    
        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(new UserDetailsService() {
                @Override
                public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
                    User user = userRepository.findOneByUsername(s);
    
                    if (null == user) {
                        // leave that to be handled by log listener
                        throw new UsernameNotFoundException("The user with email " + s + " was not found");
                    }
    
                    return (UserDetails) user;
                }
            }).passwordEncoder(passwordEncoder);
        }
    
    
        @Configuration
        @EnableAuthorizationServer
        protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
    
    
    
            @Autowired
            private AuthenticationManager authenticationManager;
    
    
            @Bean
            public JwtAccessTokenConverter accessTokenConverter() {
                return new JwtAccessTokenConverter();
            }
    
            @Override
            public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
                oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
            }
    
            @Override
            public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
                endpoints.authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
            }
    
    
            @Override
            public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                clients.inMemory()
                        .withClient("xxx")
                        .resourceIds(xxx)
                        .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                        .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                        .scopes("read", "write", "trust", "update")
                        .accessTokenValiditySeconds(xxx)
                        .refreshTokenValiditySeconds(xxx)
                        .secret("xxx")
    
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

这些配置存在于不同的类中,并且手动设置排序.

有没有人解决这个问题?

最好,

Kam*_*kol 20

我试图调整您的安全配置.不幸的是,由于缺少参考应用程序,我无法验证此配置.

也许它可以帮助你:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
                User user = userRepository.findOneByUsername(s);

                if (null == user) {
                    throw new UsernameNotFoundException("The user with email " + s + " was not found");
                }

                return (UserDetails) user;
            }
        }).passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity
                .ignoring()
                .antMatchers("/resources/**"
                        , "/templates/**"
                        , "/login"
                        , "/logout"
                        , "/ui/**"
                        , "/401.html"
                        , "/404.html"
                        , "/500.html");
    }

    @Configuration
    @EnableAuthorizationServer
    public static class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;

        @Bean
        public JwtAccessTokenConverter accessTokenConverter() {
            return new JwtAccessTokenConverter();
        }

        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
        }


        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                    .withClient("xxx")
                    .resourceIds("xxx")
                    .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                    .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                    .scopes("read", "write", "trust", "update")
                    .accessTokenValiditySeconds(xxx)
                    .refreshTokenValiditySeconds(xxx)
                    .secret("xxx");

        }
    }

    @Configuration
    @Order(1)
    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                    .csrf().disable()
                    .authorizeRequests()
                    .antMatchers("/ui/admin.xhtml").hasAnyAuthority("admin", "ADMIN")
                    .antMatchers("/thymeleaf").hasAnyAuthority("admin", "ADMIN")
                    .and()
                    .formLogin()
                    .loginPage("/login")
                    .defaultSuccessUrl("/ui/index.xhtml")
                    .failureUrl("/login?error=1")
                    .permitAll()
                    .and()
                    .logout()
                    .permitAll()
                    .and()
                    .rememberMe()
                    .and().exceptionHandling().accessDeniedPage("/error/403");
        }
    }

    @Order(2)
    @Configuration
    @EnableResourceServer
    public static class CustomResourceServerConfigurerAdapter extends ResourceServerConfigurerAdapter {

        @Bean
        ApplicationListener<AbstractAuthorizationEvent> loggerBean() {
            return new AuthenticationLoggerListener();
        }

        @Bean
        AccessDeniedHandler accessDeniedHandler() {
            return new AccessDeniedExceptionHandler();
        }

        @Bean
        AuthenticationEntryPoint entryPointBean() {
            return new UnauthorizedEntryPoint();
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);
            if (contentNegotiationStrategy == null) {
                contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
            }
            MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
                    MediaType.APPLICATION_FORM_URLENCODED,
                    MediaType.APPLICATION_JSON,
                    MediaType.MULTIPART_FORM_DATA);

            http.authorizeRequests()
                    .and()
                    .anonymous().disable()
                    .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and().httpBasic()
                    .and()
                    .exceptionHandling()
                    .accessDeniedHandler(accessDeniedHandler()) // handle access denied in general (for example comming from @PreAuthorization
                    .authenticationEntryPoint(entryPointBean()) // handle authentication exceptions for unauthorized calls.
                    .defaultAuthenticationEntryPointFor(entryPointBean(), preferredMatcher)
                    .and()
                    .authorizeRequests()
                    .antMatchers("/api/**").fullyAuthenticated();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)