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

查看:1227
本文介绍了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天全站免登陆