Spring Boot 中的基本 Auth + oAuth 实现

Posted

技术标签:

【中文标题】Spring Boot 中的基本 Auth + oAuth 实现【英文标题】:Basic Auth + oAuth Implementation in Spring Boot 【发布时间】:2018-05-17 13:21:00 【问题描述】:

我正在尝试在springboot中实现Basic Auth + oAuth2, 表示登录系统后,有些 url 应该像传统方式一样工作,有些应该在 AOuth2 上工作。

就像我想允许访问管理面板的 SuperAdmin,网址从

开始

/superAdmin/****

我只想在一般登录系统后访问所有这些url。

Rest 服务应该在 AOuth2 上使用 url 开始表单

/api/vi/****

这些网址用于向申请人提供访问权限。

单独两个都可以正常工作,但是两个一起都不能工作。

这是我的配置。

import in.kpis.tracking.configuration.CustomAuthenticationSuccessHandler;
import in.kpis.tracking.service.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;

@Configuration
public class OAuth2ServerConfiguration 

    protected static final String RESOURCE_ID = "restservice";

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter 

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) 
            // @formatter:off
            resources.resourceId(RESOURCE_ID);
            // @formatter:on
        

        @Override
        public void configure(HttpSecurity http) throws Exception 
            http
                    .authorizeRequests()
                    .antMatchers("/api/v1/*").hasRole("ADMIN")
                    .antMatchers("/greeting").authenticated();
        
    


    @Configuration
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter 

        @Autowired
        private AdminUserService adminUserService;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception 
            auth.userDetailsService(adminUserService);
        

        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception 
            return super.authenticationManagerBean();
        

    

    @Configuration
    @Order(1)
    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter 
        @Override
        protected void configure(HttpSecurity http) throws Exception 

            String[] permitAll = new String[]"/error";
            String[] permitToSuperAdmin = new String[]
                    "/superAdmin/*",
            ;

            http.authorizeRequests()
                    .antMatchers(permitToSuperAdmin).access("hasRole('SUPER_ADMIN')")
                    .antMatchers("/login").permitAll()
                    .and().formLogin().loginPage("/userLogin.html")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .loginProcessingUrl("/login")
                    .successHandler(new CustomAuthenticationSuccessHandler())
                    .and()
                    .logout().logoutSuccessUrl("/userLogin.html?logout")
                    .deleteCookies("JSESSIONID")
                    .invalidateHttpSession(true);
            http.csrf().disable();
        
    

【问题讨论】:

here "/api/v1/*" 这个 url 将被 Admin 在其他平台上使用 REST API,所以我需要添加 OAuth2,而另一方面,系统将由 "SUPER_ADMIN" 更新通过使用spring security登录系统,所以order 1配置与superadmin有关。 【参考方案1】:

如果您需要为应用程序的不同部分设置不同的安全设置,则需要创建单独的 Spring Security @Configuration-s,其中每个将只配置一种身份验证机制。每个配置都应该指定它所覆盖的 URI,并且配置需要是@Order-ed。没有 @Order 注释的配置被认为是最后一个 - 后备。在 Spring Security 参考手册中是 described。

所以你需要三个配置:

    一个用于http.antMatcher("/superAdmin/**")...@Order(1)。 一个用于 API http.antMatcher("/api/vi/**")...@Order(2)。 未对其他资源进行身份验证的后备配置,未指定 @Order 注释。

【讨论】:

现在它允许我使用 oAuth 调用 api,但我仍然无法像传统方式那样登录。 您需要致电http.antMatcher(...)。它很容易与http.authorizeRequests().antMatchers(...) 混淆,但它是不同的。 嘿,我不确定它是否会一起工作,看我再次更新问题,但是这个配置不起作用,如果我评论 Order 1 配置它将与 oAuth 一起使用,并且登录身份验证不起作用,如果我取消注释 Order 1 配置,则 oAuth 身份验证将不起作用并且登录开始工作。【参考方案2】:

好问题 为了将oAuth与spring security一起使用,我认为没有任何方法可以使用它。 您需要创建两个不同的项目,一个是用于一般 sec。一个用于 oAuth。

【讨论】:

至少有一种方法可以做到这一点:***.com/questions/50061662/… 和此问题中的其他答案指向其他选项。【参考方案3】:

这实际上已经在Multiple HttpSecurity下的Spring安全指南中进行了解释

@Configuration
@Order(1)                                                        2
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter 
    protected void configure(HttpSecurity http) throws Exception 
        http
            .antMatcher("/api/**")                               3
            .authorizeRequests()
                .anyRequest().hasRole("ADMIN")
                .and()
            .httpBasic();
    


@Configuration                                                   4
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin();
    

要使用资源服务器保护 OAuth2 端点,您可以按如下方式配置资源服务器

@Configuration
@EnableResourceServer
@Order(1)
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter 



    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception 
        resources.resourceId("resource-id");
    

    @Override
    public void configure(HttpSecurity http) throws Exception 
        http.requestMatcher(new OAuthRequestedMatcher())
            .authorizeRequests().anyRequest().fullyAuthenticated();

    


private static class OAuthRequestedMatcher implements RequestMatcher 
    public boolean matches(HttpServletRequest request) 
        String auth = request.getHeader("Authorization");
        boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
        boolean haveAccessToken = request.getParameter("access_token")!=null;
        return haveOauth2Token || haveAccessToken;
    

【讨论】:

以上是关于Spring Boot 中的基本 Auth + oAuth 实现的主要内容,如果未能解决你的问题,请参考以下文章

每个请求的 Spring Boot Basic Auth,为以后的请求验证用户名

在 spring-boot 中删除其中一个 Web API 上的 Auth Filter

Spring-boot 为辅助 SSL 侦听器配置 client-auth=need

使用基本身份验证配置 Spring Boot 的嵌入式 tomcat 容器

spring-boot Actuator 连同 Spring Security 和 Form Basic Auth

4种Spring Boot 实现通用 Auth 认证方式