Spring security oauth2 和表单登录配置 [英] Spring security oauth2 and form login configuration

查看:71
本文介绍了Spring security oauth2 和表单登录配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My project consists exposes two different parts, a JSF admin panel and a RESTfull service. I am trying to setup spring security to use different authentication methods depending on the URL the user navigates.

要求是

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

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

The seperate configurations work by themselves, the problem is when I try to combine both of them in one configuration, in that case it seems like the REST provider gets in the way and authenticates each request even if the requests go to the admin url (this is documented from spring security ordering).

我的示例配置如下所示:

My sample configurations are as shown:

  • 对于表单登录(JSF)

  • For the form login (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");

  • OAuth2 安全配置 (REST)

  • OAuth2 security config (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")
    
            }
        }
    }
    

  • 这些配置存在于不同的类上,并且顺序是手动设置的.

    These configurations exist on different classes and the ordering is set manually.

    有没有人对此问题有任何解决方案?

    Has anyone any solutions to this issue?

    最好,

    推荐答案

    我尝试调整您的安全配置.很遗憾,由于缺少参考应用程序,我无法验证此配置.

    I tried to adapt your security configuration. Unfortunately, I can not validate this configuration due to missing reference application.

    也许可以帮到你:

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

    这篇关于Spring security oauth2 和表单登录配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆