Spring安全oauth2和表单登录配置

Spring安全oauth2和表单登录配置,spring,spring-security,oauth-2.0,spring-java-config,Spring,Spring Security,Oauth 2.0,Spring Java Config,我的项目包含两个不同的部分,一个JSF管理面板和一个RESTfull服务。 我正在尝试设置SpringSecurity,根据用户导航的URL使用不同的身份验证方法 要求如下: 导航到JSF页面的用户将获得一个登录屏幕,在该屏幕上,他们使用表单身份验证进行身份验证 导航到REST服务的用户对令牌授予使用OAuth2隐式身份验证和基本身份验证 单独的配置可以自己工作,问题是当我尝试将它们结合在一个配置中时,在这种情况下,REST提供者似乎会妨碍并验证每个请求,即使请求转到管理url(这在spri

我的项目包含两个不同的部分,一个JSF管理面板和一个RESTfull服务。 我正在尝试设置SpringSecurity,根据用户导航的URL使用不同的身份验证方法

要求如下:

  • 导航到JSF页面的用户将获得一个登录屏幕,在该屏幕上,他们使用表单身份验证进行身份验证
  • 导航到REST服务的用户对令牌授予使用OAuth2隐式身份验证和基本身份验证
单独的配置可以自己工作,问题是当我尝试将它们结合在一个配置中时,在这种情况下,REST提供者似乎会妨碍并验证每个请求,即使请求转到管理url(这在spring安全排序中有记录)

我的示例配置如下所示:

  • 用于表单登录(JSF)

  • OAuth2安全配置(REST)

    @EnableResourceServer
    @订单(2)
    公共类RestSecurityConfig扩展了WebSecurity配置适配器{
    @注入
    私有用户存储库用户存储库;
    @注入
    专用密码编码器;
    @豆子
    ApplicationListener loggerBean(){
    返回新的AuthenticationLoggerListener();
    }
    @豆子
    AccessDeniedHandler AccessDeniedHandler(){
    返回新的AccessDeniedExceptionHandler();
    }
    @豆子
    AuthenticationEntryPoint entryPointBean(){
    返回新的UnauthorizedEntryPoint();
    }
    /*凌驾
    public void configure(WebSecurity web)引发异常{
    忽略
    蚂蚁配对者(
    “/resources/**”
    ,“/templates/**”
    ,“/login”
    ,“/注销”
    ,“/ui/**”
    ,“/401.html”
    ,“/404.html”
    ,“/500.html”
    );
    }*/
    @凌驾
    受保护的无效配置(HttpSecurity http)引发异常{
    ContentNegotiationStrategy ContentNegotiationStrategy=http.getSharedObject(ContentNegotiationStrategy.class);
    if(contentNegotiationStrategy==null){
    contentNegotiationStrategy=新的HeaderContentNegotiationStrategy();
    }
    MediaTypeRequestMatcher preferredMatcher=新的MediaTypeRequestMatcher(contentNegotiationStrategy,
    MediaType.APPLICATION\u FORM\u URLENCODED,
    MediaType.APPLICATION_JSON,
    MediaType.MULTIPART\u FORM\u DATA);
    http.authorizeRequests()
    .antMatchers(“/ui/**”).permitAll()
    .及()
    .anonymous().disable()
    .会议管理()
    .sessionCreationPolicy(sessionCreationPolicy.STATELESS)
    .and().httpBasic()
    .及()
    .例外处理()
    .accessDeniedHandler(accessDeniedHandler())//处理通常拒绝的访问(例如从@PreAuthorization提交)
    .authenticationEntryPoint(entryPointBean())//处理未经授权调用的身份验证异常。
    .defaultAuthenticationEntryPointFor(entryPointBean(),preferredMatcher)
    .及()
    .授权请求()
    .antMatchers(“/api/**”).fullyAuthenticated();
    }
    @凌驾
    @豆子
    公共AuthenticationManager authenticationManagerBean()引发异常{
    返回super.authenticationManagerBean();
    }
    @凌驾
    受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
    auth.userDetailsService(新的userDetailsService(){
    @凌驾
    public UserDetails loadUserByUsername(字符串s)引发UsernameNotFoundException{
    User User=userRepository.findOneByUsername;
    if(null==用户){
    //让日志侦听器来处理
    抛出新UsernameNotFoundException(“未找到带有电子邮件“+s+”的用户”);
    }
    返回(UserDetails)用户;
    }
    }).密码编码器(passwordEncoder);
    }
    @配置
    @EnableAuthorizationServer
    受保护的静态类OAuth2Config扩展了AuthorizationServerConfigurerAdapter{
    @自动连线
    私人AuthenticationManager AuthenticationManager;
    @豆子
    公共JwtAccessTokenConverter accessTokenConverter(){
    返回新的JwtAccessTokenConverter();
    }
    @凌驾
    public void configure(AuthorizationServerSecurityConfigure oauthServer)引发异常{
    oauthServer.tokenKeyAccess(“isAnonymous()| | hasAuthority('ROLE_TRUSTED_CLIENT'))”)。checkTokenAccess(“hasAuthority('ROLE_TRUSTED_CLIENT')”);
    }
    @凌驾
    public void configure(AuthorizationServerEndpointsConfigurer端点)引发异常{
    endpoints.authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
    }
    @凌驾
    公共无效配置(ClientDetailsServiceConfigurer客户端)引发异常{
    clients.inMemory()
    .与客户(“xxx”)
    .ResourceId(xxx)
    .authorizedGrantTypes(“密码”、“授权码”、“刷新令牌”、“隐式”)
    .权限(“角色客户”、“角色受信任客户”)
    .scopes(“读取”、“写入”、“信任”、“更新”)
    .accessTokenValiditySeconds(xxx)
    .refreshTokenValiditySeconds(xxx)
    .秘密(“xxx”)
    }
    }
    }
    
这些配置存在于不同的类中,并且顺序是手动设置的

有人能解决这个问题吗


最好,

我尝试调整您的安全配置。不幸的是,我无法验证该配置
@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");
@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")

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